Перейти к содержанию
    

SDC: ответ на CMD8 не корректен

Доброго времени суток. Работаю с микроконтроллером AT91SAM7X512 и SD картой памяти малого объема (2Гб).

При передаче команды CMD0 принимают ответ 0х01, как и положено.

Далее - по блок-схеме из спецификации на SD карту памяти, передаю команду CMD8 и получаю ответ (первый байт является байтом ответа R1) 0хС1, хотя должен получить так же 0х01.

Соответственно, данная ситуация выбила дальнейшую инициализацию SD карты из колеи.

Почему карта первым байтом ответа R7 (коим по идее должен быть ответ R1) является байт, значение которого равно 0хС1?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему карта первым байтом ответа R7 (коим по идее должен быть ответ R1) является байт, значение которого равно 0хС1?

Тут возможны варианты:

- Вы просто не дожидаетесь ответа на CMD8 (0xC1 надо проигнорировать и ждать дальше нулевого значения в седьмом бите)

- Карта не поддерживает CMD8. У разных карт реакция разная - некоторые просто игнорируют CMD8, другие отвечают "illegal command" и т.п.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Опрос ответа на команду со стороны ведущего устройства организовал верно.

А что получается - заменить SD карту памяти на другую?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что получается - заменить SD карту памяти на другую?

Зачем же? Считать, что карта не поддерживает версию 2.0, и работать с ней как с 1.01.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но ведь она не шлет ответ R7 как таковой.

Она шлет что-то типа R7, только вместо первого байта у нее в старшей тетраде не то, что предполагает ответ R1 - значение, старший бит которого равен 0.

Например, 00000001 - хороший ответ, 00000101 - значение, соответствующее указателю на нелегальную команду. А у меня значение 11000001 - старшие биты в старшей тетрады не с 0 начинаются.

А если как ты говорил выше, искать первый бит, равный 0 - у нас происходит тогда "сдвиг" принимаемых данных - мы будем посылать значение - и в ответ приходить будет не то, что надо.

Следовательно, как делаю я:

1) Отправил CMD0

2) Принял ответ R1, равный 0х01 (как и надо)

3) Отправил CMD8

4) Шлю значение 0xFF, пока не получу ответ, отличающийся от 0xFF, затем этот ответ шлю в USART - и смотрю на компе.

5) принимаю остальные байты ответа R7.

 

Может задержку какую-нибудь делать между CMD0 и CMD8?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может задержку какую-нибудь делать между CMD0 и CMD8?

Каких-либо специальных задержек там не нужно. Искать в ответе байт, отличный от 0xFF, неправильно. Если в течение восьми передач нуля в седьмом бите не последовало, значит нет ответа на команду.

 

Можете написать, что передается в CMD8 и что возвращается в ответ (скажем, просто 16 байт после команды)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это программа, которая передает команду CMD8 [0x48 00 00 01 AA 87] SD карте памяти.

Как видно, первый байт, пришедший в USART, равен 0xFF, это значение на линии MISO после отправки последнего байта команды CMD8.

// Передача команды CMD8

SPI_Enable(AT91C_BASE_SPI0); // Включение SPI0

SPI_Write(AT91C_BASE_SPI0, 1, 0x48); // Запись первого байта команды CMD0

response=SPI_Read(AT91C_BASE_SPI0); // В ответе 0xFF

SPI_Write(AT91C_BASE_SPI0, 1, 0x00); // Запись второго байта команды CMD0

response=SPI_Read(AT91C_BASE_SPI0); // В ответе 0xFF

SPI_Write(AT91C_BASE_SPI0, 1, 0x00); // Запись третьего байта команды CMD0

response=SPI_Read(AT91C_BASE_SPI0); // В ответе 0xFF

SPI_Write(AT91C_BASE_SPI0, 1, 0x01); // Запись четвертого байта команды CMD0

response=SPI_Read(AT91C_BASE_SPI0); // В ответе 0xFF

SPI_Write(AT91C_BASE_SPI0, 1, 0xAA); // Запись пятого байта команды CMD0

response=SPI_Read(AT91C_BASE_SPI0); // В ответе 0xFF

SPI_Write(AT91C_BASE_SPI0, 1, 0x87); // Запись шестого(последнего) байта команды CMD0

response=SPI_Read(AT91C_BASE_SPI0); // В ответе 0xFF

 

USART_Write(AT91C_BASE_US0, response, 0);

for(a=0; a<16; ++a)

{

SPI_Write(AT91C_BASE_SPI0, 1, 0xFF); // Сдвиг "1" на линию данных

response=SPI_Read(AT91C_BASE_SPI0); // Чтение данных

USART_Write(AT91C_BASE_US0, response, 0);

}

SPI_Disable(AT91C_BASE_SPI0); // Отключение SPI

Итак, что приходит по USART:

FF FF C1 7F FF FF FF FF FF FF FF FF FF FF FF FF FF

Вот все что приходит после передачи команды CMD8.

Итак первый байт - 0xFF - Это после передачи последнего байта 0x87 команды CMD8.

Байты [2...17] в вышеприведенных сведениях - это все, что принимает SPI при отправке 0xFF SD карте памяти (ведь ответ нужно ожидать, удерживая линию MOSI в высоком логическом уровне, т.е. передавать 0xFF).

Похоже, ответ R7 (первый байт которого определяется ответом R1) таков:

C1 7F FF FF FF

Но это ни в какие рамки не вписывается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Похоже, ответ R7 (первый байт которого определяется ответом R1) таков:

C1 7F FF FF FF

Но это ни в какие рамки не вписывается.

Хм, если C17F сдвинуть на пару бит влево, то получится ответ "illegal command".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну да, получается так. Но, ведь как так получается, ведь и ответы и сами команды являются байт-ориентированными, т.е. четко разграничиваются сигналом CS.

А если сдвигать байты влево - это получится, что уже время NCR не кратно байту.

Кстати, насчет того, как проверять ответы.

На многих сайтах сделано именно так - опрашивать линию MISO до тех пор, пока не придет ответ, отличный от 0xFF - и в зависимости от него решать, что делать.

Да и время NCR - оно всегда кратно байту, не может в байте ответа содержаться биты предыдущего принятого байта... Ведь это перекосяк какой-то получается.

В данном случае на 2 бита ответ сдвинулся, а другую команду передам - вообще гадость будет - и гадай тут, на сколько бит что сдвигать, чтобы что-то внятное получилось.

Допустим, нужно проверять ответ - пока не встретится "0" в старшем бите принятого байта.

Но маркеры ответов на данные имеют другой формат, например - 11111110 или 11111100, тут уже никак не угадаешь, на сколько что куда сдвигать.

А о маркерах ошибки вообще молчу - там значения приходят такие:

ххх0data1

- тут о проверке первого принятого бита забыть можно, его значение может быть любым...

Странное поведение SD...

Вроде бы все по байтам четко должно быть разграничено.

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На многих сайтах сделано именно так - опрашивать линию MISO до тех пор, пока не придет ответ, отличный от 0xFF - и в зависимости от него решать, что делать.

Я не видел еще ни одной приличной реализации работы SD-SPI на просторах интернета.

У R1, 2, 3 и т.п. есть вполне четкий отличительный признак: "0" в старшем бите. Если искать "не 0xFF", работать в большинстве случаев будет. Но не будет соответствовать спецификации.

 

Вроде бы все по байтам четко должно быть разграничено.

Оно и разграничено на самом деле. Я это к тому, не проскакивает ли в вашей системе на SCK чего лишнего?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы предположил еще что nCS успевает вернуться в неактивное состояние. Лучше бы SPI_WriteBuffer или не пользоваться либами, а написать самому.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не видел еще ни одной приличной реализации работы SD-SPI на просторах интернета.

У R1, 2, 3 и т.п. есть вполне четкий отличительный признак: "0" в старшем бите. Если искать "не 0xFF", работать в большинстве случаев будет. Но не будет соответствовать спецификации.

 

 

Оно и разграничено на самом деле. Я это к тому, не проскакивает ли в вашей системе на SCK чего лишнего?

Для ответов на команды - это хороший отличительный знак, что старшие биты всегда имеют значение "0".

Но есть и ответы на данные, маркеры ошибок и т.д.

А там не всегда в старших битах значение "0".

Кстати, насчет линии SCK - может от того, что я линию CS в неактивное состояние не перевожу, а сразу прямо выключаю SPI?

Я бы предположил еще что nCS успевает вернуться в неактивное состояние. Лучше бы SPI_WriteBuffer или не пользоваться либами, а написать самому.

Нет. В настройках SPI я определил, что линия CS не будет устанавливаться в высокий логический уровень при передаче.

Я когда передачу и окончательный прием заканчиваю, выключаю SPI - при этом аппаратно линия CS устанавливается в лог. "1".

 

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для ответов на команды - это хороший отличительный знак, что старшие биты всегда имеют значение "0".

Но есть и ответы на данные, маркеры ошибок и т.д.

А там не всегда в старших битах значение "0".

У маркеров данных и кодов ошибок есть свои отличительные признаки. И в каждом случае заведомо известно, что ожидается от карты.

 

Кстати, насчет линии SCK - может от того, что я линию CS в неактивное состояние не перевожу, а сразу прямо выключаю SPI?

Очень даже может.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошо, попробую не выключать SPI после последней передачи.

Тогда, если обобщенно сделать вывод о протоколе SPI-SD: никто толком интерфейс не разбирал (в смысле разработчики SD), и ожидать от карты можно чего угодно? :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда, если обобщенно сделать вывод о протоколе SPI-SD: никто толком интерфейс не разбирал (в смысле разработчики SD), и ожидать от карты можно чего угодно? :)

Нет. Не разбирали многочисленные "писатели", не стесняющиеся выкладывать в сети свои шедевры на тему SD-SPI.

 

Все карты, которые мне до сих пор встречались, работали строго в соответствии со спецификацией. Все они без исключения отлично работают в SPI-режиме.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...