У меня есть специальная плата на основе микроконтроллера ST Microelectronics STM32F103VE с картой MiniSD, подключенной к шине SDIO микроконтроллера. Электрические соединения были выполнены в точности так, как указано на схеме платы STM3210E-EVAL , проверены и перепроверены, поэтому я уверен, что они правильные. К сожалению, у меня нет той платы eval, чтобы проверить, является ли то, что я испытываю, аппаратной проблемой, но это не так. Для тестов, приведенных ниже, я использую карту памяти Kingston 2 ГБ MicroSD (модель MBLYG2 / 2 ГБ), купленную совсем недавно (поэтому она должна соответствовать новейшей спецификации SD-карты) с прилагаемым адаптером MicroSD - MiniSD; еще не тестировал с другими картами.
Я следую упрощенной спецификации физического уровня карты SD, чтобы понять, что происходит. Код, который я использую, является примером кода SDIO, который поставляется со стандартной периферийной библиотекой ST Micro для этого микроконтроллера. Он начинается с отправки CMD0 (GO_IDLE_STATE), затем CMD8 (SEND_IF_COND), а затем ACMD41 (SD_SEND_OP_COND), что выполняется путем отправки CMD55 (APP_CMD), за которым следует CMD41. Линия тактовых частот работает на частоте 400 кГц, и в рамках моих усилий по отладке я добавил задержку около 100 тактовых циклов между CMD0 и CMD8, поскольку я где-то читал, что это требовалось, по крайней мере, при работе в SPI Режим. За исключением модификаций, упомянутых ниже, код точно такой же, как пример кода.
Когда я впервые попытался запустить пример кода, у CMD55 возникла проблема, которая возникла из-за того, что микроконтроллер буферизовал ответ на CMD8, но образец кода не получил ответ CMD8, поэтому при проверке ответа на CMD55, код фактически смотрел на ответ на CMD8 и был расстроен этим. Я исправил эту проблему, сняв флажок CMDREND на периферии SDIO микроконтроллера перед отправкой CMD55, поэтому, когда код проверял ответ на CMD55, у него больше не было буферизованного ответа CMD8.
Следующая проблема, на которой я сейчас застрял, заключается в том, что в ответ на CMD55 установлен бит 23 поля состояния карты (COM_CRC_ERROR), который указывает, что проверка CRC предыдущей команды завершилась неудачно в соответствии с спецификация Хотя микроконтроллер автоматически вычисляет CRC, я подключил логический анализатор к схеме, чтобы убедиться, что он был правильным. Я использую веб-приложение (извините, не могу связать, потому что я новый пользователь, но просто Google для "CRC ghsi" и это первый результат), чтобы проверить CRC, используя полином x ^ 7 + x ^ 3 + 1 согласно спецификации. Это вывод логического анализатора, отформатированный и прокомментированный мной:
// uC sends CMD0, CRC OK, no response:
01 000000 00000000000000000000000000000000 1001010 1
// uC sends CMD8, CRC OK, check byte = 0xAA:
01 001000 00000000000000000000000110101010 1000011 1
// SD card responds to CMD8, CRC OK, check byte echoed back = 0xAA:
00 001000 00000000000000000000000110101010 0001001 1
// uC sends CMD55, CRC OK:
01 110111 00000000000000000000000000000000 0110010 1
// SD card responds to CMD55, CRC OK, note card status bits 23, 8 and 5 set;
// bit 23 = COM_CRC_ERROR, bit 8 = READY_FOR_DATA and bit 5 = APP_CMD:
00 110111 00000000100000000000000100100000 0000100 1
Также обратите внимание, что если я попытаюсь сделать CMD55 во второй раз сразу после обмена, указанного выше, бит 23 сбрасывается:
// uC sends CMD55, CRC OK:
01 110111 00000000000000000000000000000000 0110010 1
// SD card responds to CMD55, CRC OK, bits 8 and 5 still set but 23 not set:
00 110111 00000000000000000000000100100000 1000001 1
Обратите внимание, что я пытался отправить CMD8 дважды перед отправкой CMD55, но это не имело никакого значения, первый CMD55 всегда возвращает установленный бит 23. Я могу воспроизвести это каждый раз, когда пытаюсь, поэтому я не верю, что это проблема с глюками или шумом. Учитывая, что значения CRC рассчитываются самим микроконтроллером, они выглядят корректно с точки зрения внешнего объекта (логического анализатора) и были проверены на веб-сайте, о котором я упоминал выше, я не вижу, как проверка CRC карты могла давать сбой.
Это как-то ожидается? Может быть, мне следует подождать установленное количество тактов между каждой командой (где-то, что я читаю, должно быть 8 циклов, и я считаю, что я уважаю это)? Могу ли я просто отправить второй CMD55, если первый не получится и будет в пути, или будут какие-то негативные последствия? Даже если это решит проблему, мне бы очень хотелось узнать, почему проверка CRC не проходит, так как я не думаю, что я делаю что-то не так.