Полная версия этой страницы:
Проблема с записью на sdcard
Добрый день.
Использую sd карту Kingston 2Gb в spi режиме. Все было хорошо, пока не закупили
карты другого производителя Silicon Power 2Gb. Суть проблемы в следующем. Данные
записываются в мультиблочном режиме(ACMD23+CMD25). После посылки первого блока
данных карта возвращает Data Response Token = Data accepted, а для последующих блоков
Data Response Token вообще не приходит(принимается 0xff). После некоторого числа попыток
ACMD23+CMD25 карта благополучно зависает и перестает отвечать вообще до пересброса питания.
Просадок по питанию во время работы нет, неиспользуемые линии через 10к подтянуты к +3.3В.
Частота spi = 12,5МГц. Пробовал частоту уменьшать в два раза, не помогает.
Знающие люди, подскажите в чем может быть дело.
_4afc_
Jan 18 2017, 19:37
Цитата(scout @ Jan 18 2017, 20:18)
После посылки первого блока данных карта возвращает Data Response Token = Data accepted, а для последующих блоков
Data Response Token вообще не приходит(принимается 0xff).
Делал чтение, и судя по моим исходникам надо ждать когда 0xff сменится на 0xfе:
Код
esint8 sd_readSectorM(hwInterface_t *iface,euint32 address, euint8* buf, euint16 len)
{
static u32 oldaddress=0xfffffff0;
u08 cardresp;
u08 firstblock;
u16 fb_timeout=0xffff;
u32 place;
if ((oldaddress+1)!=address)
{
sd_Command(iface,12, 0,0);//STOP_TRANSMISSION
cardresp=sd_Resp8b(iface); /* Card response */
place=512*address;
sd_Command(iface,18, (euint16) (place >> 16), (euint16) place);//READ_MULTIPLE_BLOCK
cardresp=sd_Resp8b(iface); /* Card response */
if(cardresp!=0x00)
{
sd_Resp8bError(iface,cardresp);
return(-1);
}
}
// Wait for startblock
do
firstblock=sd_Resp8b(iface);
while(firstblock==0xff && fb_timeout--);
if( firstblock!=0xfe)
{
sd_Resp8bError(iface,firstblock);
return(-1);
}
sd_spiPDC_RD512(iface,&buf[0],len);
oldaddress=address;
return(0);
}
Спасибо за ответ. Но у меня проблема с записью. При мультиблочном чтении я так же как и Вы дожидаюсь
приема 0xfe. Хотя мультиблочное чтение именно на этой карте я еще не проверял...
Попробовал несколько карт других производителей - на первый взгляд таких проблем нет.
А с картой Silicon Power такой затык. И именно их мы закупили...
Кстати, после того, как карта зависает в ответ, например, на команду 0x55 она начинает слать
0x01 - типа "я нахожусь в idle state".
Встречал посты товарища aaarrr, кажется он уже собаку съел на sd картах.
aaarrr, может быть Вы что подскажите?
aaarrr
Jan 19 2017, 11:49
Цитата(scout @ Jan 19 2017, 13:11)
aaarrr, может быть Вы что подскажите?
Давайте попробую. Только напишите максимально подробно, что происходит после приема токена "Data Accepted" от первого блока. Прямо по шагам.
Что я вижу.
После посылки первого блока данных я получаю в ответ корректный Data Token, после чего карта
держит "Busy" в течении примерно 12мс. После того, как карта отпустила "Busy", я посылаю второй
блок данных, после чего карта Busy уже не отпускает. Да, CS на время Busy я снимаю, т.к на spi
у меня живут еще несколько устройств.
aaarrr
Jan 19 2017, 15:41
Цитата(scout @ Jan 19 2017, 17:37)
После того, как карта отпустила "Busy", я посылаю второй блок данных, после чего карта Busy уже не отпускает.
В первом сообщении было:
Цитата
... для последующих блоков Data Response Token вообще не приходит(принимается 0xff)
Так в какой момент возникает Busy?
Токен данных не перепутан? Должен быть 0xFE для одиночных записей и 0xFC для многоблочных.
Прошу прощения за неточность описания. Сейчас поясню.
Поведение Busy вообще загадка.
Как я уже писал, после посылки первого блока Busy держится около 12мс.
После отпускания Busy посылается второй блок данных, при этом линия D0 после начала передачи держится в "1" один клок, после чего
падает в "0", т.е вместо Data Response Token я читаю 0x00. Однако через уже примерно 2мс карта отпускает D0, т.е снимает
Busy и если дальше передавать блоки, то все последующие Data Response Token будут уже равны 0xff.
Через некоторое время после такой записи карта начинает в ответ на любую команду возвращать 0x01.
P.S. Токен при мультиблочной записи шлю верный - 0xFC.
aaarrr
Jan 20 2017, 01:02
Похоже, что-то не так у Вас с определением конца сигнализации Busy, потому как это описание
Цитата(scout @ Jan 19 2017, 19:43)
После отпускания Busy посылается второй блок данных, при этом линия D0 после начала передачи держится в "1" один клок, после чего
падает в "0"...
полностью соответствует поведению карты в том случае, когда выдача Busy возобновляется после снятого CS - один период шина в "1", далее снова "0".
aaarrr, благодарю Вас за советы.
Ситуация проясняется. Busy я определяю как наличие 0xff
на DAT0. Рассматриваю процесс записи на осциллографе и вижу,
что через ~12 мс после передачи первого блока на DAT0 я действительно
вижу 0xff. То есть по моему мнению Busy карта сняла.
Далее я отпускаю CS карты и считываю данные следующего для
записи блока данных из внешней RAM, которая тоже сидит на том же spi.
Далее я снова опускаю CS карты и передаю второй блок, после которого
Data Response я уже не получаю.
Так вот, если я убираю обращение к внешней RAM - запись на карту
восстанавливается, на передачу всех блоков я начинаю получать
корректный response.
Сижу ломаю голову, каким образом чтение из внешней RAM влияет на запись в
SD. Единственное, что приходит в голову - карта во время чтения из RAM
решает чем - то заняться и опускает Busy(карта продолжает тактироваться клоками во время чтения из RAM),
о чем я, естественно, не догадываюсь, т.к проверял Busy раньше и уверен, что карта свободна.
Немного изменил алгоритм записи на карту. Теперь чтение очередного блока из внешней
RAM я делаю до проверки сигнала занятости карты. Так вот, ситуация изменилась, стало еще
интереснее.
Теперь корректные Data Response я получаю в ответ на посылки первых двух блоков.
В качестве Data Response на посылки остальных блоков я получаю 0xff, после чего вижу, что карта
как ни в чем не бывало выставляет Busy. Такое ощущение, что карте не нравится, когда ее тактируют при снятом сигнале
Busy. Видимо чтение из внешней RAM для 3-го и последующих блоков происходит
когда карта уже освободилась(после посылки первого блока карта выставляет Busy на ~12мс, после передачи остальных блоков Busy
снимается гораздо быстрей, через ~2мс)..
Кто-нибудь что-нибудь может сказать по этому поводу?
aaarrr
Jan 20 2017, 13:31
После отпускания CS карты не забыли холостую передачу на SPI?
Цитата
После отпускания CS карты не забыли холостую передачу на SPI?
Не забыл, dummy байт передается.
У меня такое ощущение, что карта игнорирует CS и ловит байты, которые
предназначаются другим устройствам на шине.
Может ли быть такое, если карта неправильно проинициализировалась,
например не перешла в "spi mode"(насколько я знаю в "sd mode", который
у карты по умолчанию, CS для работы не требуется)?
aaarrr
Jan 20 2017, 14:02
Цитата(scout @ Jan 20 2017, 16:43)
У меня такое ощущение, что карта игнорирует CS и ловит байты, которые
предназначаются другим устройствам на шине.
Похоже, да. Если честно, я бы не рискнул использовать такое включение карты.
Цитата(scout @ Jan 20 2017, 16:43)
Может ли быть такое, если карта неправильно проинициализировалась,
например не перешла в "spi mode"(насколько я знаю в "sd mode", который
у карты по умолчанию, CS для работы не требуется)?
Нет, тогда бы она вообще не работала.
Цитата
Похоже, да. Если честно, я бы не рискнул использовать такое включение карты.
Почему же? Это же обычная практика для spi устройств использовать одну шину
и раздельные CS.
aaarrr
Jan 20 2017, 14:26
Цитата(scout @ Jan 20 2017, 17:22)
Почему же? Это же обычная практика для spi устройств использовать одну шину
и раздельные CS.
Для SPI устройств - да, но SD карта все же не является нативным SPI устройством.
Благодарю за ответы, думаю на этом тема исчерпана.
Кстати, заметил один нюанс: data response перестает приходить, если
CS поднимается при сброшенном Busy. Т.е, заканчивается передача данных,
приходит response token, я вижу, что Busy падает в "0", а пока я готовлюсь
поднять CS, Busy уже успевает перейти в "1" и, спустя некоторое время,
CS поднимается в "1". И именно после этого пропадают data response.
Насколько критично поднимать CS при сброшенном Busy?
aaarrr
Jan 20 2017, 19:18
Цитата(scout @ Jan 20 2017, 20:00)
Насколько критично поднимать CS при сброшенном Busy?
Резонный вопрос! Карта в этот момент уже ждет токена данных. Возможно, тут есть какой-то глюк с её стороны.
Попробуйте сделать так: передача блока - прием Data Response Token - работа с другим CS - выборка карты с ожиданием Busy.
Цитата
Попробуйте сделать так: передача блока - прием Data Response Token - работа с другим CS - выборка карты с ожиданием Busy.
Я так и делаю! Проблема в том, что начиная с третьего блока карта после передачи Response Token держит Busy очень короткое время,
поэтому я не успеваю поднять CS. И именно после этого начинаются проблемы. Похоже эта особенность поведения данной карты является непреодолимой и придется всю запись переделать с использованием одиночных блоков.
Цитата(scout @ Jan 21 2017, 12:29)
Проблема в том, что начиная с третьего блока карта после передачи Response Token держит Busy очень короткое время,
поэтому я не успеваю поднять CS.
Как это возможно??? Неуспевание.
Все процессы на шине SPI тактируются мастером (Вашим контроллером). Соответственно - Вы можете в любой момент "остановить время" на шине SPI просто остановив SCLK.
Цитата
Как это возможно??? Неуспевание.
Все процессы на шине SPI тактируются мастером (Вашим контроллером). Соответственно - Вы можете в любой момент "остановить время" на шине SPI просто остановив SCLK.
После получения Response Token я посылаю dummy байт и, насколько я помню, сразу после этого
карта отпускает Busy. После посылки холостого байта я опускаю CS и посылаю еще один dummy байт.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.