Arlleex 131 13 ноября, 2011 Опубликовано 13 ноября, 2011 · Жалоба Доброго времени суток. Работаю с микроконтроллером AT91SAM7X512 и SD картой памяти малого объема (2Гб). При передаче команды CMD0 принимают ответ 0х01, как и положено. Далее - по блок-схеме из спецификации на SD карту памяти, передаю команду CMD8 и получаю ответ (первый байт является байтом ответа R1) 0хС1, хотя должен получить так же 0х01. Соответственно, данная ситуация выбила дальнейшую инициализацию SD карты из колеи. Почему карта первым байтом ответа R7 (коим по идее должен быть ответ R1) является байт, значение которого равно 0хС1? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 13 ноября, 2011 Опубликовано 13 ноября, 2011 · Жалоба Почему карта первым байтом ответа R7 (коим по идее должен быть ответ R1) является байт, значение которого равно 0хС1? Тут возможны варианты: - Вы просто не дожидаетесь ответа на CMD8 (0xC1 надо проигнорировать и ждать дальше нулевого значения в седьмом бите) - Карта не поддерживает CMD8. У разных карт реакция разная - некоторые просто игнорируют CMD8, другие отвечают "illegal command" и т.п. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 13 ноября, 2011 Опубликовано 13 ноября, 2011 · Жалоба Опрос ответа на команду со стороны ведущего устройства организовал верно. А что получается - заменить SD карту памяти на другую? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 13 ноября, 2011 Опубликовано 13 ноября, 2011 · Жалоба А что получается - заменить SD карту памяти на другую? Зачем же? Считать, что карта не поддерживает версию 2.0, и работать с ней как с 1.01. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба Но ведь она не шлет ответ 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба Может задержку какую-нибудь делать между CMD0 и CMD8? Каких-либо специальных задержек там не нужно. Искать в ответе байт, отличный от 0xFF, неправильно. Если в течение восьми передач нуля в седьмом бите не последовало, значит нет ответа на команду. Можете написать, что передается в CMD8 и что возвращается в ответ (скажем, просто 16 байт после команды)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба Это программа, которая передает команду 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 Но это ни в какие рамки не вписывается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба Похоже, ответ R7 (первый байт которого определяется ответом R1) таков: C1 7F FF FF FF Но это ни в какие рамки не вписывается. Хм, если C17F сдвинуть на пару бит влево, то получится ответ "illegal command". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 14 ноября, 2011 Опубликовано 14 ноября, 2011 (изменено) · Жалоба Ну да, получается так. Но, ведь как так получается, ведь и ответы и сами команды являются байт-ориентированными, т.е. четко разграничиваются сигналом CS. А если сдвигать байты влево - это получится, что уже время NCR не кратно байту. Кстати, насчет того, как проверять ответы. На многих сайтах сделано именно так - опрашивать линию MISO до тех пор, пока не придет ответ, отличный от 0xFF - и в зависимости от него решать, что делать. Да и время NCR - оно всегда кратно байту, не может в байте ответа содержаться биты предыдущего принятого байта... Ведь это перекосяк какой-то получается. В данном случае на 2 бита ответ сдвинулся, а другую команду передам - вообще гадость будет - и гадай тут, на сколько бит что сдвигать, чтобы что-то внятное получилось. Допустим, нужно проверять ответ - пока не встретится "0" в старшем бите принятого байта. Но маркеры ответов на данные имеют другой формат, например - 11111110 или 11111100, тут уже никак не угадаешь, на сколько что куда сдвигать. А о маркерах ошибки вообще молчу - там значения приходят такие: ххх0data1 - тут о проверке первого принятого бита забыть можно, его значение может быть любым... Странное поведение SD... Вроде бы все по байтам четко должно быть разграничено. Изменено 14 ноября, 2011 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба На многих сайтах сделано именно так - опрашивать линию MISO до тех пор, пока не придет ответ, отличный от 0xFF - и в зависимости от него решать, что делать. Я не видел еще ни одной приличной реализации работы SD-SPI на просторах интернета. У R1, 2, 3 и т.п. есть вполне четкий отличительный признак: "0" в старшем бите. Если искать "не 0xFF", работать в большинстве случаев будет. Но не будет соответствовать спецификации. Вроде бы все по байтам четко должно быть разграничено. Оно и разграничено на самом деле. Я это к тому, не проскакивает ли в вашей системе на SCK чего лишнего? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DmitryM 0 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба Я бы предположил еще что nCS успевает вернуться в неактивное состояние. Лучше бы SPI_WriteBuffer или не пользоваться либами, а написать самому. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 14 ноября, 2011 Опубликовано 14 ноября, 2011 (изменено) · Жалоба Я не видел еще ни одной приличной реализации работы SD-SPI на просторах интернета. У R1, 2, 3 и т.п. есть вполне четкий отличительный признак: "0" в старшем бите. Если искать "не 0xFF", работать в большинстве случаев будет. Но не будет соответствовать спецификации. Оно и разграничено на самом деле. Я это к тому, не проскакивает ли в вашей системе на SCK чего лишнего? Для ответов на команды - это хороший отличительный знак, что старшие биты всегда имеют значение "0". Но есть и ответы на данные, маркеры ошибок и т.д. А там не всегда в старших битах значение "0". Кстати, насчет линии SCK - может от того, что я линию CS в неактивное состояние не перевожу, а сразу прямо выключаю SPI? Я бы предположил еще что nCS успевает вернуться в неактивное состояние. Лучше бы SPI_WriteBuffer или не пользоваться либами, а написать самому. Нет. В настройках SPI я определил, что линия CS не будет устанавливаться в высокий логический уровень при передаче. Я когда передачу и окончательный прием заканчиваю, выключаю SPI - при этом аппаратно линия CS устанавливается в лог. "1". Изменено 14 ноября, 2011 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба Для ответов на команды - это хороший отличительный знак, что старшие биты всегда имеют значение "0". Но есть и ответы на данные, маркеры ошибок и т.д. А там не всегда в старших битах значение "0". У маркеров данных и кодов ошибок есть свои отличительные признаки. И в каждом случае заведомо известно, что ожидается от карты. Кстати, насчет линии SCK - может от того, что я линию CS в неактивное состояние не перевожу, а сразу прямо выключаю SPI? Очень даже может. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба Хорошо, попробую не выключать SPI после последней передачи. Тогда, если обобщенно сделать вывод о протоколе SPI-SD: никто толком интерфейс не разбирал (в смысле разработчики SD), и ожидать от карты можно чего угодно? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба Тогда, если обобщенно сделать вывод о протоколе SPI-SD: никто толком интерфейс не разбирал (в смысле разработчики SD), и ожидать от карты можно чего угодно? :) Нет. Не разбирали многочисленные "писатели", не стесняющиеся выкладывать в сети свои шедевры на тему SD-SPI. Все карты, которые мне до сих пор встречались, работали строго в соответствии со спецификацией. Все они без исключения отлично работают в SPI-режиме. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться