|
SDC: ответ на CMD8 не корректен |
|
|
|
Nov 14 2011, 09:51
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Но ведь она не шлет ответ 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?
|
|
|
|
|
Nov 14 2011, 15:44
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Это программа, которая передает команду 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 Но это ни в какие рамки не вписывается.
|
|
|
|
|
Nov 14 2011, 16:57
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Ну да, получается так. Но, ведь как так получается, ведь и ответы и сами команды являются байт-ориентированными, т.е. четко разграничиваются сигналом CS. А если сдвигать байты влево - это получится, что уже время NCR не кратно байту. Кстати, насчет того, как проверять ответы. На многих сайтах сделано именно так - опрашивать линию MISO до тех пор, пока не придет ответ, отличный от 0xFF - и в зависимости от него решать, что делать. Да и время NCR - оно всегда кратно байту, не может в байте ответа содержаться биты предыдущего принятого байта... Ведь это перекосяк какой-то получается. В данном случае на 2 бита ответ сдвинулся, а другую команду передам - вообще гадость будет - и гадай тут, на сколько бит что сдвигать, чтобы что-то внятное получилось. Допустим, нужно проверять ответ - пока не встретится "0" в старшем бите принятого байта. Но маркеры ответов на данные имеют другой формат, например - 11111110 или 11111100, тут уже никак не угадаешь, на сколько что куда сдвигать. А о маркерах ошибки вообще молчу - там значения приходят такие: ххх0data1 - тут о проверке первого принятого бита забыть можно, его значение может быть любым... Странное поведение SD... Вроде бы все по байтам четко должно быть разграничено.
Сообщение отредактировал Arlleex - Nov 14 2011, 17:24
|
|
|
|
|
Nov 14 2011, 18:35
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Arlleex @ Nov 14 2011, 20:57)  На многих сайтах сделано именно так - опрашивать линию MISO до тех пор, пока не придет ответ, отличный от 0xFF - и в зависимости от него решать, что делать. Я не видел еще ни одной приличной реализации работы SD-SPI на просторах интернета. У R1, 2, 3 и т.п. есть вполне четкий отличительный признак: "0" в старшем бите. Если искать "не 0xFF", работать в большинстве случаев будет. Но не будет соответствовать спецификации. Цитата(Arlleex @ Nov 14 2011, 20:57)  Вроде бы все по байтам четко должно быть разграничено. Оно и разграничено на самом деле. Я это к тому, не проскакивает ли в вашей системе на SCK чего лишнего?
|
|
|
|
|
Nov 14 2011, 19:36
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(aaarrr @ Nov 14 2011, 22:35)  Я не видел еще ни одной приличной реализации работы SD-SPI на просторах интернета. У R1, 2, 3 и т.п. есть вполне четкий отличительный признак: "0" в старшем бите. Если искать "не 0xFF", работать в большинстве случаев будет. Но не будет соответствовать спецификации.
Оно и разграничено на самом деле. Я это к тому, не проскакивает ли в вашей системе на SCK чего лишнего? Для ответов на команды - это хороший отличительный знак, что старшие биты всегда имеют значение "0". Но есть и ответы на данные, маркеры ошибок и т.д. А там не всегда в старших битах значение "0". Кстати, насчет линии SCK - может от того, что я линию CS в неактивное состояние не перевожу, а сразу прямо выключаю SPI? Цитата Я бы предположил еще что nCS успевает вернуться в неактивное состояние. Лучше бы SPI_WriteBuffer или не пользоваться либами, а написать самому. Нет. В настройках SPI я определил, что линия CS не будет устанавливаться в высокий логический уровень при передаче. Я когда передачу и окончательный прием заканчиваю, выключаю SPI - при этом аппаратно линия CS устанавливается в лог. "1".
Сообщение отредактировал Arlleex - Nov 14 2011, 19:44
|
|
|
|
|
Nov 14 2011, 19:43
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Arlleex @ Nov 14 2011, 23:36)  Для ответов на команды - это хороший отличительный знак, что старшие биты всегда имеют значение "0". Но есть и ответы на данные, маркеры ошибок и т.д. А там не всегда в старших битах значение "0". У маркеров данных и кодов ошибок есть свои отличительные признаки. И в каждом случае заведомо известно, что ожидается от карты. Цитата(Arlleex @ Nov 14 2011, 23:36)  Кстати, насчет линии SCK - может от того, что я линию CS в неактивное состояние не перевожу, а сразу прямо выключаю SPI? Очень даже может.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|