Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: И снова STM32F10x, SD-Карты, SDIO и файловые системы.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
KnightIgor
Коллеги,

я понимаю, что на тему уже говорено-переговорено, но столкнулся я со странным поведением составляющих и прошу помощи.

Имеем:
- железяки с STM32F103 и с SD-картой на SPI либо SDIO.
- KEIL Flash-FS (из 4.х) и родными "драйверами" для SPI и SDIO.
- FatFS, конкретно с diskio.c, где пользуется "драйвер" SDIO из примеров от ST (часто как файл sdcard.c).
- познание в сравнении.

Итак, до сего момента работало все отлично либо как KEIL Flash-FS через SPI | SDIO с "драйверами" от KEIL, а также FatFS через SPI. Причем в последнем случае я переписал diskio.c от Martin Thomas, чтобы работа с SPI также велась через SPI-драйвер из KEIL.

Теперь возникла тема запустить FatFS через SDIO. Здесь я не стал пользовать управление SDIO от KEIL, а обратился к примерам, где diskio.c пользует sdcard.c из примеров от ST.

В принципе, заработало, но наблюдается следующий эффект: если в процессе отладки после УСПЕШНОЙ инициализации карты, сделать сброс отладки (начать сначала), то на последующем проходе карта не инициализируется, т.к. после CMD0 уже команда CMD8 (которая 0x1AA передает) не получает ответа вообще, и устанавливается бит таймаута в ->STATUS. Если карточку обесточить (вынуть и вставить), то инициализации пройдет успешно. Такое же поведение и при "нормальной" работе устройства: карту вставил, устройству дал сброс, карта прочиталась. Не вынимая карту и не снимая питания, снова устройство пересбросил - карта не прочиталась. Карту вынул-вставил, устройство перестартанул - карта прочлась. KEIL Flash-FS на том же устройстве при таких же экспериментах работает уверенно, карта готова всегда.

Мое подозрение: либо изнутри KEIL Flash-FS карта инициализируется иначе, чем это реализовано в diskio.c + sdcard.c, либо где-то временнЫе соотношения иные. Предварю вопрос: частоты тактирования SDIO идентичны как под KEIL, так и под ST-драйверами.

Куда смотреть еще?
AHTOXA
Попробуйте паузу ~10 мс после CMD0. Слышал, что может помочьsm.gif
KnightIgor
Цитата(AHTOXA @ Sep 10 2014, 19:41) *
Попробуйте паузу ~10 мс после CMD0. Слышал, что может помочьsm.gif

Та-а-а-к. Сделал. Вроде помогло. Однако возникает риторический вопрос: куда смотрели писатели sdcard.c, и как работает у других?

P.S. Помогло лишь тем, что всегда CMD8 отвечать стала. А затем вообще интересный эффект стал наблюдаться:

сбросил - проинициализировал - пошло чтение - успешно.
сбросил - проинициализировал - пошло чтение - ошибка SDIO_FLAG_DCRCFAIL.
сбросил - проинициализировал - пошло чтение - успешно.
сбросил - проинициализировал - пошло чтение - ошибка SDIO_FLAG_DCRCFAIL.

и.т.д., четко чередуясь.

"А тут слух пустили, что скоро водку в бумажных пакетах продавать будут. Как жить - не знаю..." (с) Г. Горин.
Genadi Zawidowski
И с новыми картами всё работет без непонятных задержек...
Вот кусок:
Код
// set MMC in Idle mode
// Вызывается, подразумевая что CS установлен
static char mmcGoIdle(void)
{
    unsigned char response;
    unsigned long cmd58answer, cmd8answer = 0;

    SDCARD_CS_HIGH();
    spi_read_byte(targetsdcard, 0xff);
    SDCARD_CS_LOW();

    spi_read_byte(targetsdcard, 0xff);
    //Send Command 0 to put MMC in SPI mode
    mmcSendCmdCRC7(MMC_GO_IDLE_STATE, 0);    // CMD0 - Обязательно с правильным CRC
    //Now wait for READY RESPONSE
    if ((response = mmcGetResponseR1()) != 0x01)
    {
        return MMC_INIT_ERROR;
    }

    spi_read_byte(targetsdcard, 0xff);

    mmcSendCmdCRC7(MMC_SEND_IF_COND, 0x000001aa);    // CMD8 - Обязательно с правильным CRC. 3.3 Volt VCC
    response = mmcGetResponseR7(& cmd8answer);
    if ((response & 0x04) != 0)    // illegal command or pattern not match
    {
        mmcAddressMultiplier = MMC_SECTORSIZE;
        mmcCardVersion2 = 0;

        // if no responce
        // Ver2.00 or later SD Memory Card(voltage mismatch)
        // or Ver1.X SD Memory Card
        // or not SD Memory Card
        debug_printf_P(PSTR("Ver1.X SD Memory Card or not SD Memory Card\n"));

        // check voltage range here
KnightIgor
Цитата(Genadi Zawidowski @ Sep 10 2014, 21:45) *
И с новыми картами всё работет без непонятных задержек...
Вот кусок:

Я так понял, это SPI. С SPI проблем нет. Есть проблемы с SDIO.
AHTOXA
Цитата(KnightIgor @ Sep 11 2014, 01:10) *
"...Как жить - не знаю..." (с) Г. Горин.

Как жить, как жить... Ставить ключ на питание, это, имхо, единственный железобетонный вариант.

Добавлю пару хоороших ссылок про SDIO.
- Статья про тонкости SDIO;
- Хорошая, простая и очень понятная либа для SDIO.
adnega
В спецификации SD довольно часто встречается фраза: мол, после этого карта находится в режиме, из которого возможен выход лишь сбросом питания. Например, перевод в режим SPI. Даже название специальное есть "power cycle".
KnightIgor
Цитата(AHTOXA @ Sep 11 2014, 06:26) *
Как жить, как жить... Ставить ключ на питание, это, имхо, единственный железобетонный вариант.

"Поздно пить Боржоми". Железо сковано уже, остыло и отвердело.
В общем, наковырял я следующую тему: в "драйвере" от обстоятельного немца господина Кайля есть такая специальная обработка случая ошибки контрольной суммы, которая, по слухам, обходит errat'у. Выглядит так:
CODE

if (stat & SDIO_STA_CCRCFAIL) {
SDIO->ICR = stat & SDIO_STA_CLEAR_MASK;
if ((cmd == SEND_OP_COND) ||
(cmd == SEND_APP_OP_COND) ||
(cmd == STOP_TRANS)) {
SDIO->CMD = 0;
break;
}
return (__FALSE);
}

Как видно, драйвер "забил большой байт" на ошибку CRC для трех команд и промыл трубу. Одна из команд - та самая расхожая ACMD41, а другая - CMD12, что после многоблочной передачи выдается. Этой заворушки нет в индусских драйверах от "MCD Application Team" sdcard.c. В качестве эксперимента я перенаправил работу с SDIO из файла sdcard.c в драйвер от KEIL. Конечно, если наложить шум на сигнал, будет шум, а не сигнал. Я вычистил индусский код, текст стал раз в пять короче, но без содрогания не взглянешь. Однако заработало! Можно сбрасывать туда-сюда, карта все равно оживляется... Как-то так. (с) Винни-Пух.

AHTOXA
Аминь sm.gif
Кстати, если используете DMA, то гляньте вот этот топик.
Там описана ещё одна нетривиальная проблема с SDIO.
KnightIgor
Цитата(AHTOXA @ Sep 11 2014, 17:38) *
Аминь sm.gif
Кстати, если используете DMA, то гляньте вот этот топик.
Там описана ещё одна нетривиальная проблема с SDIO.

Спасибо за тему. Действительно, драйвер KEIL использует DMA (и только DMA!), причем словный (U32). С неприятностями невыравнивания под FatFS я пока не столкнулся, может еще и потому, что использую FatFS (во всяком случае в рамках топика) в конфигурации только для чтения в загрузчике.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.