Перейти к содержанию
    

Проблема с инициализацией SD карты

Делаю устройство типа логгера, которое пишет инфу на SD карточку. Использую проц C8051F930 и фаловую систему от Chan FS. Раньше использовал старенькую вериси 0.05 и работал c SD карточками. Но вот недавно купил карту 4GB SHDC Кингстон 4X. И вот появилась проблема с иницалищацией. Она не проходит.

Старый код такой:

/*-----------------------*/
/* Initialize Disk Drive */
/* (Platform dependent)  */

DSTATUS disk_initialize(BYTE drv /* Physical drive nmuber (0..) */)
{
BYTE data i = drv;
BYTE data n;
unsigned int data nn;

POWER_ON();					/* Socket power ON */

for (nn = 3000; nn; nn--)
	;	

Stat |= STA_NOINIT;
if (!(Stat & STA_NODISK))
{
	n = 10;						/* Dummy clock */
	do
	{
		rcvr_spi();
	}
	while (--n);

	SELECT();			/* CS = L */

	if (send_cmd(CMD0, 0) == 1)
	{
		/* Enter Idle state */
		Timer = 10000;					/* Wait for card ready in timeout of 1 sec */

		while (Timer-- && send_cmd(CMD1, 0))
		{
			;}

		if (Timer > 0)
		{
			Stat &= ~STA_NOINIT;
		}	/* When device goes ready, clear STA_NOINIT */
	}

	DESELECT();			/* CS = H */

	rcvr_spi();			/* Idle (Release DO) */
}

if (Stat & STA_NOINIT)
{
	disk_shutdown();
}

return Stat;
}

 

Он отлично работает с SD картами но не работает с SHDC.

Посмотрел последнюю версию фата и там в примерах есть инициализация с поддержкой SHDC, но он тоже сходу не заработал.

DSTATUS disk_initialize (
BYTE drv		/* Physical drive nmuber (0) */
)
{
BYTE n, cmd, ty, ocr[4];


if (drv) return STA_NOINIT;			/* Supports only single drive */
if (Stat & STA_NODISK) return Stat;	/* No card in the socket */

power_on();							/* Force socket power on */
FCLK_SLOW();
for (n = 10; n; n--) rcvr_spi();	/* 80 dummy clocks */

ty = 0;
if (send_cmd(CMD0, 0) == 1) {			/* Enter Idle state */
	Timer1 = 100;						/* Initialization timeout of 1000 msec */
	if (send_cmd(CMD8, 0x1AA) == 1) {	/* SDv2? */
		for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();		/* Get trailing return value of R7 resp */
		if (ocr[2] == 0x01 && ocr[3] == 0xAA) {				/* The card can work at vdd range of 2.7-3.6V */
		 while (Timer1 && send_cmd(ACMD41, 1UL << 30));     /* Wait for leaving idle state (ACMD41 with HCS bit) */
			if (Timer1 && send_cmd(CMD58, 0)== 0) {		/* Check CCS bit in the OCR */
				for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
				ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* SDv2 */
			}
		}
	} else {							/* SDv1 or MMCv3 */
		if (send_cmd(ACMD41, 0) <= 1) 	{
			ty = CT_SD1; cmd = ACMD41;	/* SDv1 */
		} else {
			ty = CT_MMC; cmd = CMD1;	/* MMCv3 */
		}
		while (Timer1 && send_cmd(cmd, 0));			/* Wait for leaving idle state */
		if (!Timer1 || send_cmd(CMD16, 512) != 0)	/* Set R/W block length to 512 */
			ty = 0;
	}
}
CardType = ty;
deselect();

if (ty) {			/* Initialization succeded */
	Stat &= ~STA_NOINIT;		/* Clear STA_NOINIT */
	FCLK_FAST();
} else {			/* Initialization failed */
	power_off();
}

return Stat;
}

 

Тут send_cmd(ACMD41, 1UL << 30)); не возвращает 0. Всегда возвращает 0x01.

и send_cmd(CMD58, 0) тоже возвращает не 0 и соответственно инициализация не проходит. Тип карты не определяется.

 

Мож кто уже наступал на такие грабли c инициализацией карты?

Заранее спасибо!

 

send_cmd(ACMD41, 1UL << 30)) возвращает всегда 0x01

send_cmd(CMD58, 0) возвращает всегда 0x05

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

send_cmd(CMD8, 0x1AA) - при отправке колманды CRC считается? Не только CMD0, но и этой ТРЕБУЕТСЯ правильный CRC.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Он отлично работает с SD картами но не работает с SHDC.

 

На сайте Atmel'a есть пакет примеров под последние ARM9. В том числе про SD карты. Я пробывал SDHC до 8 Gb все работает. Только там, где будете вычислять объем, придется перейти на 64-битные переменные (если вам будет нужен объем в байтах).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На сайте Atmel'a есть пакет примеров под последние ARM9. В том числе про SD карты. Я пробывал SDHC до 8 Gb все работает. Только там, где будете вычислять объем, придется перейти на 64-битные переменные (если вам будет нужен объем в байтах).

C проблемой разобрался. Там при отправке ACMD41 передавался 0 вместо 1<<30. Кейл компилил не правильно.

Теперь со всеми картами работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...