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

    
Сколько клоков закладывать в хитрое место?

А почему это Вас сильно волнует? При наличии контроля responce после каждого байта этот "таймаут" может заложен весьма большим.

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


Ссылка на сообщение
Поделиться на другие сайты
А почему это Вас сильно волнует? При наличии контроля responce после каждого байта этот "таймаут" может заложен весьма большим.

Насколько большим?

Если он будет мЕньшим, чем нужен для конкретной карты, то после ACMD 41 я получу responce 0хFF, и буду повторять ACMD 41 до бесконечности (пробовал 255 раз, результата никакого). Поэтому хочется или знать какое-то значение, при котором любая SDHC карта, поддерживающая SPI, ответит 0х00, или понять, где я чего-то неправильно сделал

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


Ссылка на сообщение
Поделиться на другие сайты
Если он будет мЕньшим, чем нужен для...

Не понимаю, что Вы там написали, но вообще бесконтрольные магические клоки на карту выдавать просто не надо. То, что перед командой, это ожидание готовности. Ожидание готовности ТОЖЕ должно быть подконтрольным и после CMD55 перед ACMD41 сначала надо дождаться готовности. Лично у меня это отсчитывает операционка, посему не с тактах :(, а в ms - 750ms почему? За давностью лет не помню :( все было написано лет пять назад.

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


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

Sorry, неправильно выразился. Это просто байты 0хFF(т.е. 8 клоков=1 байт), передаваемые при неактивном CS (как те, что до CMD 0).

Т.е. после CMD 55 достаточно дать паузу ~800 мС, затем CMD 41?

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


Ссылка на сообщение
Поделиться на другие сайты
неправильно выразился. Это просто байты 0хFF(

Я о том-же. Вот и КОНТРОЛИРУЙТЕ ответ-готовность при передаче этих 0xFF.

Т.е. после CMD 55 достаточно дать паузу ~800 мС, затем CMD 41?

Разумеется нет. Пауза тут вообще ни сном ни духом CD надо тактировать. Считать при этом время или байт-такты, это уже конкретная реализация.

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


Ссылка на сообщение
Поделиться на другие сайты
Вот и КОНТРОЛИРУЙТЕ ответ-готовность при передаче этих 0xFF.

Чего-то я, видимо, не понимаю. Как я могу контролировать? Responce на CMD55 я уже получил. CMD 41 еще не передавал. Только что специально все ответы на посланные 64 байта (т.е. 512 клоков) сложил в RAM, после Responce на CMD 41 посмотрел - все 0хFF. Да и как карта может отвечать, если CS неактивен?

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


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

Это правильная реакция карты готовой к приему команды ее и надо ждать, а вот CS должен быть активен во время всей "большой" команды ACMD.

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


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

Передаю CMD55, жду responce 0x01, CS оставляю активным, отправляю байты 0хFF до тех пор, пока не получу ответ 0хFF, отправляю CMD 41, жду responce 0x00, если таймаут, повторяю все сначала.

Если делаю так, то всю большую ACMD 41 повторяю от 5 до 8 раз.

Если так,как раньше (т.е. отправляю 64 байта 0хFF) то повторяю 4 раза.

Самые "медленно отвечающие" карты смогу проверить завтра.

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


Ссылка на сообщение
Поделиться на другие сайты
Передаю 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 );

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


Ссылка на сообщение
Поделиться на другие сайты
А вот проходить все должно БЕЗ таймаута с первого раза.

Всем доброго дня.

Проверил "медленноотвечающие" карты.

Обе 8 Gb карты не работают :( После >100 повторений большой ACMD 41 - таймаут.(~1 сек.)

В железе, я думаю, проблем нет - при тупой передаче 64 байт все работает

То же самое по инициализации( если по предыдущим командам получены правильные responce, значит все в норме?)

Буду разбираться...

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


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

Дабы не плодить темы, пишу сюда.

Есть в наличии плата на 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.

post-45138-1347434828_thumb.jpg

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация