|
|
|
Снова SD/MMC, Вопросы, на которые не нащел пока ответов |
|
|
|
Apr 11 2010, 18:21
|
Местный
Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180
|
Цитата(zltigo @ Apr 11 2010, 19:59) А почему это Вас сильно волнует? При наличии контроля responce после каждого байта этот "таймаут" может заложен весьма большим. Насколько большим? Если он будет мЕньшим, чем нужен для конкретной карты, то после ACMD 41 я получу responce 0хFF, и буду повторять ACMD 41 до бесконечности (пробовал 255 раз, результата никакого). Поэтому хочется или знать какое-то значение, при котором любая SDHC карта, поддерживающая SPI, ответит 0х00, или понять, где я чего-то неправильно сделал
|
|
|
|
|
Apr 11 2010, 18:54
|
Гуру
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244
|
Цитата(forever_student @ Apr 11 2010, 20:36) Если он будет мЕньшим, чем нужен для... Не понимаю, что Вы там написали, но вообще бесконтрольные магические клоки на карту выдавать просто не надо. То, что перед командой, это ожидание готовности. Ожидание готовности ТОЖЕ должно быть подконтрольным и после CMD55 перед ACMD41 сначала надо дождаться готовности. Лично у меня это отсчитывает операционка, посему не с тактах , а в ms - 750ms почему? За давностью лет не помню все было написано лет пять назад.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 11 2010, 19:14
|
Местный
Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180
|
Цитата(zltigo @ Apr 11 2010, 23:09) ... бесконтрольные магические клоки на карту выдавать просто не надо... Sorry, неправильно выразился. Это просто байты 0хFF(т.е. 8 клоков=1 байт), передаваемые при неактивном CS (как те, что до CMD 0). Т.е. после CMD 55 достаточно дать паузу ~800 мС, затем CMD 41?
|
|
|
|
|
Apr 11 2010, 19:22
|
Гуру
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244
|
Цитата(forever_student @ Apr 11 2010, 21:29) неправильно выразился. Это просто байты 0хFF( Я о том-же. Вот и КОНТРОЛИРУЙТЕ ответ-готовность при передаче этих 0xFF. Цитата Т.е. после CMD 55 достаточно дать паузу ~800 мС, затем CMD 41? Разумеется нет. Пауза тут вообще ни сном ни духом CD надо тактировать. Считать при этом время или байт-такты, это уже конкретная реализация.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 11 2010, 19:54
|
Местный
Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180
|
Цитата Вот и КОНТРОЛИРУЙТЕ ответ-готовность при передаче этих 0xFF. Чего-то я, видимо, не понимаю. Как я могу контролировать? Responce на CMD55 я уже получил. CMD 41 еще не передавал. Только что специально все ответы на посланные 64 байта (т.е. 512 клоков) сложил в RAM, после Responce на CMD 41 посмотрел - все 0хFF. Да и как карта может отвечать, если CS неактивен?
|
|
|
|
|
Apr 11 2010, 20:39
|
Местный
Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180
|
Передаю CMD55, жду responce 0x01, CS оставляю активным, отправляю байты 0хFF до тех пор, пока не получу ответ 0хFF, отправляю CMD 41, жду responce 0x00, если таймаут, повторяю все сначала. Если делаю так, то всю большую ACMD 41 повторяю от 5 до 8 раз. Если так,как раньше (т.е. отправляю 64 байта 0хFF) то повторяю 4 раза. Самые "медленно отвечающие" карты смогу проверить завтра.
|
|
|
|
|
Apr 11 2010, 21:36
|
Гуру
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244
|
Цитата(forever_student @ Apr 11 2010, 22:54) Передаю CMD55, жду responce 0x01, CS оставляю активным, отправляю байты 0хFF до тех пор, пока не получу ответ 0хFF, отправляю CMD 41, жду responce 0x00, если таймаут, повторяю все сначала. Да. Теперь правильно. У меня, правда, один 0xFF сначала передается бесконтрольно. Почему уже не помню что там читал 4-5 лет назад, возможно просто как минимально необходимый. Цитата Если делаю так, то всю большую ACMD 41 повторяю от 5 до 8 раз. А вот проходить все должно БЕЗ таймаута с первого раза. Начните внимательно разбираться по первоисточнику с самого начала инициализации. Или с железом проблемы. Успехов! А, на счет с первого раза - у меня есть и повтор. Зачем? Опять не помню . В ветка, первой версии SD, или MMC повтора нет, а для продвинутой есть. Пора по первоисточникам освежать память.... Код // The card can work at vdd range of 2.7-3.6V do { // ACMD41 with HCS bit if( send_cmd_app( ACMD41_OPERATE, BIT30 ) == R1_OK ) { if( send_cmd( CMD58_OCR, 0 ) == R1_OK ) { // Check CCS bit mmc_receiveblock( sd_buf, 4 ); if( sd_buf[0] & 0x40 ) Mds.ctype = (CARD_SD|CARD_V2X|CARD_BLOCK); else Mds.ctype = (CARD_SD|CARD_V2X); } } } while( xIsTimeout( timer ) == FALSE );
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 12 2010, 05:31
|
Местный
Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180
|
Цитата(zltigo @ Apr 12 2010, 01:51) А вот проходить все должно БЕЗ таймаута с первого раза. Всем доброго дня. Проверил "медленноотвечающие" карты. Обе 8 Gb карты не работают После >100 повторений большой ACMD 41 - таймаут.(~1 сек.) В железе, я думаю, проблем нет - при тупой передаче 64 байт все работает То же самое по инициализации( если по предыдущим командам получены правильные responce, значит все в норме?) Буду разбираться...
|
|
|
|
|
Sep 12 2012, 07:27
|
Участник
Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138
|
Дабы не плодить темы, пишу сюда. Есть в наличии плата на LPC2378. Карта памяти подключена к модулю MCI по схеме, которую прилагаю к посту. Модуль MCI инициализирую следующим образом: Код void MCI_init (void) { unsigned char i=0;
//процедура инициализации карты памяти PCONP |=(1<<28); //Включаем тактирование модуля MCI //На время инициализации запрещаем все прерывания MCI_MASK0=0; MCI_MASK1=MCI_MASK0; //PINSEL1=0x2280; //Активируем выводы контроллера карт памяти PINSEL1=0x00002A80; PINSEL4=0x0A800000; //Задаем режим тактирования по-умолчанию, сбрасываем требуемые регистры MCI_COMMAND=0; MCI_DATA_CTRL=0; MCI_CLEAR=0x7FF; //Сбрасываем все отложенные прерывания MCI_POWER=0x02; //Подаем напряжение на карту while (!(MCI_POWER & 0x02)); for (i=0;i<100;i++); //Во время идентификации тактовая частота не должна превышать 400 кГц. //После прохождения этой фазы частота тактового сигнала может быть установлена //25 МГц для SD и 20 МГц для MMC SetMCIClock(SLOW_RATE); MCI_POWER |=0x01; } Далее следует инициализация карты памяти Код unsigned char init_card (void) { unsigned int i=0;
if (!(MCI_Go_Idle_State())) //Переход в неактивное состояние return 0; //Карта неизвестна else { if (MCI_Check_Ver()) //Проверка версии по команде CMD8 { send_string2("SD v2\r\n"); if (MCI_Send_ACMD_OP_Cond(OCR_INDEX_V2)) return 2; else return 0; } else { if (!(MCI_Go_Idle_State())) return 0; else { send_string2("SD v1\r\n"); MCI_Go_Idle_State(); MCI_POWER |= (1 << 6 ); // Set Open Drain output control for MMC for ( i=0; i<0x3000; i++ );
//Посылаем команду CMD1 - если карта MCC - она инициализируется if ( MCI_Send_OP_Cond()) return 1; else //В противном случае посылаем команду ACMD41 с параметром OCR_INDEX if (MCI_Send_ACMD_OP_Cond(OCR_INDEX)) return 2; else return 0; } } } } Команда ACMD41 реализуется, как CMD55+ACMD41 Функция отправки CMD55 Код unsigned char MCI_Send_ACMD( void ) { unsigned int i=0, t=0; unsigned long Argument=0; unsigned long Status=0; unsigned long Data[4]; char buf[8];
if (CardType==2) { Argument = CardRCA; //Используется адрес из команду установки относительного адреса } else { Argument = 0x00000000; //Для ММС используется аргумент 0 } for (t=0; t<0x200; t++) { MCI_SendCmd(CMD55, Argument, SHORT_RESP, 0 ); Status=MCI_GetCmdResp(CMD55, SHORT_RESP, (unsigned long*)&Data[0]); if ((!(Status)) && (Data[0] & CARD_STATUS_ACMD_ENABLE)) { send_string2("CMD55 good\r\n"); return 1; } for (i=0; i<0x50; i++); } memcpy(buf,&Status,4); send_mas2(buf,4); send_string2("CMD55 error\r\n"); return 0; } Функция отправки ACMD41. В процессе своей работы вызывает предыдущую функцию Код unsigned char MCI_Send_ACMD_OP_Cond (unsigned long Argument) { unsigned int t=0; //Счетчик попыток unsigned int i=0; //Счетчик задержек unsigned long Status=0; //Статус unsigned long Data[4]; //Данные, возвращаемые при запросе //Если процедура Send_Op_Cond вылетела по таймауту (вставлена не карта ММС), //пробуем Send_ACMD_OP_Cond MCI_POWER &= ~(1 << 6 ); /* Clear Open Drain output control for SD */ for ( i = 0; i < 0x3000; i++ ); for (t=0; t<0x200; t++) { if (!(MCI_Send_ACMD())) { continue; } else { MCI_SendCmd( ACMD41, Argument, SHORT_RESP, 0 ); Status=MCI_GetCmdResp(ACMD41, SHORT_RESP, (unsigned long *)&Data[0]); //Нулевой и второй бит должны быть в нуле иначе ошибка CRC или таймаут if (!(Status&MCI_CMD_TIMEOUT) && (Data[0] & 0x80000000)) { return 1; } for ( i=0; i<0x20; i++); //Таймаут для следующей попытки } } return 0; } Карта Tranced 2Гб нормально опознается, как карта SD V2 и проходит инициализацию нормально. Карты же Tranced 256 Мб и Tranced 1 Гб опознаются, как SD V1, но при отправке CMD55 после первой попытки в регистре статуса устанавливаются флаги Command response timeout и Command sent (no response required) - биты 3 и 8 соответственно, при последующих попытках только флаг Command response timeout. Если строки в функции MCI_Send_ACMD() Код MCI_SendCmd(CMD55, Argument, SHORT_RESP, 0 ); Status=MCI_GetCmdResp(CMD55, SHORT_RESP, (unsigned long*)&Data[0]); заменяю на Код MCI_SendCmd(CMD55, Argument, NO_RESP, 0 ); Status=MCI_GetCmdResp(CMD55, NO_RESP, (unsigned long*)&Data[0]); в регистре статуса не устанавливается ни одного флага, но и в переменной Data тоже нули. Подскажите пожалуйста, как правильно в таком случае поступить? Можно будет при втором варианте отправки CMD55 просто проверить регистр статуса (что ни один из флагов не выставлен) и сразу переходить к отправке самой ACMD41? Или обязательно нужно получить ответ? P.S. Использую среду Keil, функции отправки комманд, а также чтения ответа на команду и статуса взял из примера к LPC23xx для проверки модуля MCI.
Эскизы прикрепленных изображений
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|