Инициализация SD-карты в вопросах SPI

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

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

мой код-это все ассемблер 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.

что не так с этой картой?

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

3 ответов


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

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

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


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

для получения дополнительной информации см. "физический уровень упрощенная спецификация версия 2.00", главы "защита передачи Шины"и" чтение данных".


это важно: у меня было очень много проблем с SD / MMC-картой, пока я не узнал, что мне пришлось выберите рабочее напряжение. Вы делаете это, отправив ACMD41 с бит установлен для напряжения вы поставляете карту. Примечание:только один бит может быть выбран. Если вы не выберете напряжение или выберите более одного, он будет продолжать цикл в режиме ожидания и никогда не выйдет на некоторых SD карты.

то есть: если ваш ACMD41 продолжает отправлять ответ 0x01,вы не выбрали напряжение. Напряжение тока в битах 23 параметра 32 битов ACMD41...8. Для 3.2 V ... 3.3 V, Это бит 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 высокий в любой момент времени. Вы можете держать его все время.