Инициализация SD-карты в проблемах SPI - PullRequest
11 голосов
/ 02 марта 2010

Я посмотрел на вопрос переполнения стека Инициализация карты microSD с использованием интерфейса SPI и не нашел ответов, соответствующих моей проблеме (то есть Я еще не пробовал).

У меня похожая проблема, когда я пытаюсь получить доступ к SD-карте через интерфейс SPI микроконтроллера (в частности, HC908 ). Я попытался следовать схемам последовательности операций в спецификации Physical Layer Simplified v2.00, и, похоже, он правильно инициализируется на Transcend 1 ГБ и 2 ГБ и карте AE & C 1 ГБ. Но у меня проблемы с тремя другими случайными картами из моего тайника старых карт, которые я использовал на своей камере.

Мой код - все ассемблер HC908. Я выделил линию синхронизации SPI, и во время инициализации она работает на частоте около 350 кГц (единственный множитель скорости, который HC908 предоставляет на моей низкой тактовой частоте MCU, которая находится в пределах окна 100–400 кГц).

Вот результаты трех карт, которые не завершают мою процедуру инициализации (все выполняются последовательно без изменения какого-либо кода или параметров синхронизации):

Canon 16Meg card (labeled as SD):
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (indicates idle)
Send CMD8 [0x48000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command set local flag to indicate v1 or MMC card
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
because illegal command branch to error routine
Send CMD13 [0x4D000000000D] (show status buffer) and Loop up to 8 times waiting for high bit on response to go low
R1= 0x05 (idle and illegal command)

Флаг незаконной команды застрял? Должен ли я что-то делать после CMD8, чтобы убрать этот флаг?

SanDisk UltraII 256Meg
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD8 [0x48000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command set local flag to indicate v1 or MMC card
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send 0xFF 4 times to read OCR
OCR = 0xFFFFFFFF
Send CMD55 [0x770000000065] (1st part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD41 [0x6900000000E5] (2nd part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command, assume card is MMC
Send CMD1 [0x4100000000F9] (for MMC) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Repeat the CMD1 50 times (my arbitrary number to wait until idle clears)
Every R1 response is 0x05 (idle and illegal command)

Почему OCR все F? Не кажется правильным на всех. Кроме того, почему ACMD41 и CMD1 отвечают недопустимой командой? Сбой CMD1, потому что карта ожидает действительного ACMD после CMD55 даже с недопустимым ответом команды?

SanDisk ExtremeIII 2G:
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD8 [0x40000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? My loop shows the responses for each iteration and I got 0xFF 0xFF 0xC1 0x7F... is the card getting out of sync?)
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle and back in sync)
Send 0xFF 4 times to read OCR
OCR = 0x00FF80
Send CMD55 [0x770000000065] (1st part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x5F (??? loop responses are 0xFF 0xFF 0xF0 0x5F... again out of sync?)
Send CMD41 [0x6900000000E5] (2nd part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command, but back in sync???)
Because illegal command, assume card is MMC
Send CMD1 [0x4100000000F9] (for MMC) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? loop responses are 0xFF 0xFF 0xC1 0x7F... again out of sync?)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? loop responses are 0xFF 0xFF 0xC1 0x7F... again out of sync?)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x00 (out of idle)
Send CMD9 [0x4900000000AF] (get CSD) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x3F (??? loop responses are 0xFF 0xFF 0xC1 0x3F... again out of sync?)
Code craps out because Illegal command bit is high.

Что на земле не так с этой картой?

Иногда это происходит синхронно, а иногда нет. (Вышеприведенный шаблон повторяется .) Я выбрал его, и не вижу никаких циклов мошеннических тактов, проходящих между передачами MOSI / MISO.

Ответы [ 3 ]

22 голосов
/ 04 марта 2010

ОК ... Я нашел свою проблему. Для всех, кто сталкивается с этой проблемой, важно не забывать отправлять дополнительные 0xFF после получения ответов. Это дает карте дополнительные восемь тактов, чтобы подготовиться к следующей команде. Некоторые карты, кажется, не нуждаются в этом (например, Transcends, которые я использую), но другим это требуется.

Я фактически поместил простой цикл в начале подпрограммы 'write command', которая отправляет 0xFF, пока не получит 0xFF в качестве ответа, чтобы мне не приходилось ходить во все места, где я читал ответы, чтобы убедиться, что я поставил дополнительный отправить 0xFF. Потому что, поскольку SD-карта (обычно) работает в режиме SPI, если нет тактов, то время остается на месте.

Одна вещь, на которую я обратил внимание и до сих пор не нашла ответа (но пока это ничего не вредит), после того как я прочитал 16 байтов CSR, кажется, что есть еще 2 байта не- 0xFF что выходит ... Это CRC16? Странно, поскольку в CSR встроен CRC ...

3 голосов
/ 16 августа 2010

Если вы включили CRC (с CMD59), то да, к блокам данных будет добавлен CRC16.

Для получения дополнительной информации см. «Версия 2.00 спецификации упрощенного физического уровня», главы «Защита передачи по шине» и «Чтение данных».

2 голосов
/ 24 апреля 2014

Это важно: у меня были очень большие проблемы с картой SD / MMC, пока я не узнал, что мне пришлось выбрать рабочее напряжение . Вы делаете это, отправляя ACMD41 с битом , установленным для напряжения , которым вы снабжаете карту. Примечание: Может быть выбран только один бит . Если вы не выберете напряжение или выберете более одного значения, оно будет ПРОДОЛЖАЕТСЯ зацикливаться в состоянии ожидания и никогда не выйдет на некоторых картах SD.

То есть: если ваш ACMD41 продолжает отправлять ответ 0x01, вы не выбрали напряжение. Напряжение в битах параметра 32-битного параметра ACMD41 23 ... 8. Для 3,2 В ... 3,3 В это бит 20, например, вы можете:

acmdSDAppOpCond[2] = (1 << (20 & 7));           /* 3.2V .. 3.3V */

Это шестнадцатеричное значение 0x10, поэтому ваш ACMD41 будет выглядеть следующим образом ... 0x69 0x40 0x10 0x00 0x00 0xCD ... или если это карта SDSC ... 0x69 0x00 0x10 0x00 0x00 0x5F

Вот краткая (и неполная) таблица наиболее распространенных значений:

Bit23: 3.5V..3.6V
Bit22: 3.4V..3.5V
Bit21: 3.3V..3.4V
Bit20: 3.2V..3.3V
Bit19: 3.1V..3.2V
Bit18: 3.0V..3.1V
Bit17: 2.9V..3.0V
Bit16: 2.8V..2.9V
Bit15: 2.7V..2.8V

Вы НЕ должны переключать высокий уровень CS в ЛЮБОЙ момент времени. Вы можете держать его на низком уровне ВСЕ время.

...