Problem with detecting SD card on A3BU xplained

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello everyony,

 

I have got a problem with connecting to a SD card using he ASF functions.

When i want to check the sd card it doesn't see any SD card and gives an error.

This is the part of the code that doesn't pas.

do {
		status = sd_mmc_test_unit_ready(0);
		if (CTRL_FAIL == status) {
			printf("Card install FAIL\n\r");
			printf("Please unplug and re-plug the card.\n\r");
			/*while (CTRL_NO_PRESENT != sd_mmc_check(0)) {
			}*/
		}
	} while (CTRL_GOOD != status);

The sd_mmc_test_unit_ready check is the sd card can be used and gives a status back of the sd_card. Through USART i give feeback of the status so i can read it on the computer with hyper terminal.

Ctrl_status sd_mmc_test_unit_ready(uint8_t slot)
{
	switch (sd_mmc_check(slot))
	{
	case SD_MMC_OK:
		if (sd_mmc_ejected[slot]) {
			return CTRL_NO_PRESENT;
		}
		if (sd_mmc_get_type(slot) & (CARD_TYPE_SD | CARD_TYPE_MMC)) {
			return CTRL_GOOD;
		}
		// It is not a memory card
		return CTRL_NO_PRESENT;

	case SD_MMC_INIT_ONGOING:
		return CTRL_BUSY;

	case SD_MMC_ERR_NO_CARD:
		sd_mmc_ejected[slot] = false;
		return CTRL_NO_PRESENT;

	default:
		return CTRL_FAIL;
	}
}
sd_mmc_err_t sd_mmc_check(uint8_t slot)
{
	sd_mmc_err_t sd_mmc_err=0;

	sd_mmc_err = sd_mmc_select_slot(slot);
	if (sd_mmc_err != SD_MMC_INIT_ONGOING) {
		sd_mmc_deselect_slot();
		return sd_mmc_err;
	}

	// Initialization of the card requested
	if (sd_mmc_is_spi()? sd_mmc_spi_card_init()
			: sd_mmc_mci_card_init()) {
		sd_mmc_debug("SD/MMC card ready\n\r");
		sd_mmc_card->state = SD_MMC_CARD_STATE_READY;
		sd_mmc_deselect_slot();
		// To notify that the card has been just initialized
		// It is necessary for USB Device MSC
		return SD_MMC_INIT_ONGOING;
	}
	sd_mmc_debug("SD/MMC card initialization failed\n\r");
	sd_mmc_card->state = SD_MMC_CARD_STATE_UNUSABLE;
	sd_mmc_deselect_slot();
	return SD_MMC_ERR_UNUSABLE;
}

The problem is that is always gives the

SD_MMC_CARD_STATE_UNUSABLE

as result of the check. So far as i know is every thing connect correctly.

I'm using https://www.ghielectronics.com/catalog/product/271 to connect the SD card to the xplained boardhttp://www.atmel.com/Images/doc8394.pdf.

The poorts are connect  like

pin 10(grnd): ground of the xplained board
pin 9 (clk) : connect to SCL of xplained
pin 8 (DAT3): connect to SS of xplained
pin 6 (CMD) : connect to MOSI of xplained
pin 4 (DAT0): connect to MISO of xplained
pin 1 (3.3V): connect to 3.3V of xplained

Can anyone help me with the problem

would appreciate it :)

gr,

Rgamer.

 

[EDIT:]

Here is the ASF link of the functions http://asf.atmel.com/docs/3.22.0/xmegaau/html/group__sd__mmc__stack__group.html

Attachment(s): 

Last Edited: Thu. May 11, 2017 - 10:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The poorts are connect  like

But what about SD_CD from the socket?

 

As well as the actual interface signals to the SD/MMC card most sockets also have two physical sensors (switches) called "Card Detect" (CD) and "Write Protect" (WP). It is the CD signal - that they bring out as SD_CD that your AVR code needs to read to know if there is a card present r not. Looking at the schematic it is pulled up using a 10K. So it's presumably active low. So the AVR code should be looking for that signal being "0" to determine that there is a card in the slot.

 

In FatFs there is a timer interrupt that senses the state of WP and CD every 10ms. If it ever "sees" CD go non-active it knows that the card has been removed and possibly replaced and that there is a likely need for it to be reinitialised.

 

I don't know the ASF code but I rather suspect it will be doing something very similar. I would dig down into the code of sd_mmc_check() in ASf and find out what it's actually expecting.

 

Again in FatFs you define:

#define CS_LOW()        PORTB &= ~1                     /* CS=low */
#define CS_HIGH()       PORTB |= 1                      /* CS=high */
#define MMC_CD          (!(PINB & 0x10))        /* Card detected.   yes:true, no:false, default:true */
#define MMC_WP          (PINB & 0x20)           /* Write protected. yes:true, no:false, default:false */

(this for mega not xmega) to tell it where to look for CD and WP signals. Again an assumption but I guess ASF must have some kind of config where you tell it where to look for WP and CD?

 

PS can I just say that I hate the way ASF is held as a Git repo. To explore this I would have to create a project that checks out the files involved here - I just want some way I can browse the ASF sources without having to create a project (and know which modules to pick to include)! If I could access it I'd have a look at what that check() function does and also how it might be that you tell it which IO the WP and CD signals are on.

Last Edited: Tue. Apr 7, 2015 - 12:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the response,

 

I removed the CD and WP functions so the code will always try to init de SD card.

 

But i found a project that has a SD card functionality, but it is on a atmega. http://www.avrfreaks.net/projects/gps-tracker?skey=sd%20card

So i ported it over to my Xmega A3BU xplained board.

With adjusting the code on low lvl. This way the higher functions still work

 

For so far i tested i can create a file on the SD card and probably write and read the file.

But i'm currently testing it. So don't know for sure.

 

PS:

I know the ASF is annoying to work with, but there isn't anything better that help you work with the xmega series. In the PDF's isn't a clear register table and if you open an example project you could kind off figure it out yourself.

 

kind regards,

Rgamer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

but there isn't anything better

Including "FatFs"? I know the code presented in FatFs for AVR is for a mega (or tiny in the "foolproof" case) not xmega. But as the only hardware it touches are (a) the SPI, (b) a couple of IO and (c) a timer then I would have thought it would be pretty easy to port it to Xmega (assuming someone hasn't already). You will get much better support if you use FatFs as that's what probably 95% of AVR users who have connected SD/MMC are using (me included).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's exactly what i did. The code i ported also uses FATfs for a atmega. So i ported it to xmega by only changing the SPI, I/O's and some other little stuff. That wasn't so hard as you say.

 

But, i first tried to do that with the xmega example to let it work over spi. The xmega has een example for using FATfs, but uses it to read and write a memory block on the xplained bord trough usart-spi poort.

I tried to change it to the poorts of SPI for my SD card, but it wouldn't work. Because it didn't find the SD card or something.

 

So, it is easier to poort a working code on the atmega with spi to an xmega, then change code from an xmega example code to my preference. frown

Another reason why the ASF is annoying to use.

(also using a function that is in another file, that uses another function in another file and so on... That is something i personally hate, but yea the functionalities are wide of the xmega  so i will bear with it smiley)

Last Edited: Tue. Apr 7, 2015 - 06:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It cannot be rocket science to get the SPI on an Xmega to send/receive a byte surely?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It aint so hard as you say to let SPI work is a piece of cake. But i wanted to use the FATfs function for reading and writing an SD card.

That would save a lot of time and also give a proper use of the SD card So i can read the files on the computer if needed.

 

SPI aint hard, but letting a functionality work is something different.

I may not be the best programmer, but for me i see the difference in difficulty.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The point is that "getting SPI to work" is the only thing you need to do - FatFs does everything else for you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is the problem with the example code for FATfs xmega. I can't find the place where they select the device to read and write to.

In the example program they do

/* Mount disk*/
	printf("-I- Mount disk %d\n\r", (int)disk_dev_num);
	/* Clear file system object */
	memset(&fs, 0, sizeof(FATFS));
	res = f_mount(disk_dev_num, &fs);
	if (res != FR_OK) {
		printf("-E- f_mount pb: 0x%X\n\r", res);
		return 0;
	}

The device number here is 0. So that isn't anything special.

They coe for f_mount is:

FRESULT f_mount (
	BYTE vol,		/* Logical drive number to be mounted/unmounted */
	FATFS *fs		/* Pointer to new file system object (NULL for unmount)*/
)
{
	FATFS *rfs;


	if (vol >= _VOLUMES)		/* Check if the drive number is valid */
		return FR_INVALID_DRIVE;
	rfs = FatFs[vol];			/* Get current fs object */

	if (rfs) {
#if _FS_SHARE
		clear_lock(rfs);
#endif
#if _FS_REENTRANT				/* Discard sync object of the current volume */
		if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR;
#endif
		rfs->fs_type = 0;		/* Clear old fs object */
	}

	if (fs) {
		fs->fs_type = 0;		/* Clear new fs object */
#if _FS_REENTRANT				/* Create sync object for the new volume */
		if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;
#endif
	}
	FatFs[vol] = fs;			/* Register new fs object */

	return FR_OK;
}

Here i can't find where they select the device they wanne mount.

Am i missing something or is it something else?

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here i can't find where they select the device they wanne mount.

Why, exactly how many SD/MMC sockets have you got attached to your Xmega? Do you really have two or more and therefore need to differentiate them as "device 0" and "device 1"?!? Otherwise you just always use "0" as you (like 99.8% of the rest of us) only have one socket.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is a example code for the A3bu xplained board for using FATfs.

 

But the xplained board had a memory block mounted on it (AT45DBX). The example program uses that memory block to read and write data with FATfs.

 

That works fine, but i want to change it to only read my SD card (which is connected to SPIC poort). But i cannot find where they choose the device. I don't think that the device number has anything to do with it.

 

The functions are all referring to other functions and so on.

 

It is hard to find what it really does at a point :/

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To handle multiple drives (and especially drives of different types such as AT45 and SD) you need special implementation of the disk_*() functions. Note how disk_initialize(), disk_read(), disk_write() and so on are each passed a "physical drive number". So you would need implementations of those that did something such as:

DSTATUS disk_initialize(BYTE physDrive) {
    DSTATUS retval = STA_NODISK;
    if (physDrive == 0) {
        retval = disk_init_at45();
    }
    else if (physDrive == 1) {
        retval = disk_init_sdmmc();
    }
    etc.
    return retval;
}

As it stands I guess the supplied code has a single disk_initialiize() (and others) that basically ignores the BYTE parameter and just operates on the AT45 - they would all need to be "moved down a level" and then a wrapper such as the above introduced to respond to the single call to disk_initialize() from ff.c. You'd also need to bring the routines from mmc_avr.c into the mix - suitably renamed with something like that _sdmmc() suffix I show above.

 

You would now choose "0:" for the AT45 and "1:" for the SD/MMC

 

Before you go to all this complication ask yourself  - do you really need BOTH types of storage? If you have GB's of storage in SD/MMC then what is the actual point of a Megabyte or two in AT45?

Last Edited: Wed. Apr 8, 2015 - 09:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for the explanation,

 

I don't need the AT45. I wanted to change it so only the SD card will be used and the AT45 not.

 

But i will go with the the code i linked before that i poorted to my xmega. It is possible to create a file and write to it.

Only the reading is not working properly, but i can figure that out. Don't think that will be to hard.

 

PS: The FATfs code example is different from the atmega FATfs. So there ain't a mmc.avr.c file. But i will try to look at the FATfs of the atmega again and maybe try to poort it.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In whatever FatFs code you have there will be one file implementing the disk_*() functions. Just replace that with the mmc_avr.c from a recent FatFs and you should be good to go. The only job then is to edit the few lines of that file that interact with the GPIO and SPI and change them to Xmega equivalents.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

Able to fix the problem ?

What was the solution and what do you did to fix the issue ?

 

I'm also facing the same issue like you. Card was not able to detect and SD card init failed.

http://www.avrfreaks.net/forum/s...

 

Can you please help me on this ?

Regards,
Titus S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As you have posted that in 2 places I will lock this copy to avoid cross posting accidents. Potential responders should follow the link above.

Topic locked