at90 0 14 марта, 2011 Опубликовано 14 марта, 2011 · Жалоба Делаю устройство типа логгера, которое пишет инфу на 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 19 марта, 2011 Опубликовано 19 марта, 2011 · Жалоба send_cmd(CMD8, 0x1AA) - при отправке колманды CRC считается? Не только CMD0, но и этой ТРЕБУЕТСЯ правильный CRC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 19 марта, 2011 Опубликовано 19 марта, 2011 · Жалоба Он отлично работает с SD картами но не работает с SHDC. На сайте Atmel'a есть пакет примеров под последние ARM9. В том числе про SD карты. Я пробывал SDHC до 8 Gb все работает. Только там, где будете вычислять объем, придется перейти на 64-битные переменные (если вам будет нужен объем в байтах). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
at90 0 19 марта, 2011 Опубликовано 19 марта, 2011 · Жалоба На сайте Atmel'a есть пакет примеров под последние ARM9. В том числе про SD карты. Я пробывал SDHC до 8 Gb все работает. Только там, где будете вычислять объем, придется перейти на 64-битные переменные (если вам будет нужен объем в байтах). C проблемой разобрался. Там при отправке ACMD41 передавался 0 вместо 1<<30. Кейл компилил не правильно. Теперь со всеми картами работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться