Полная версия этой страницы:
SD/MMC
hsx_Vlad
Dec 21 2007, 18:43
Подскажите пожалуйста почему не все карточки на ARMе отзываються на команды CMD10 и CMD9 и можноли это как то обойти?
KuzmaPrytkov
Dec 21 2007, 18:59
Цитата(hsx_Vlad @ Dec 21 2007, 22:43)

Подскажите пожалуйста почему не все карточки на ARMе отзываються на команды CMD10 и CMD9 и можноли это как то обойти?
Список в студию!
zltigo
Dec 21 2007, 19:22
Цитата(KuzmaPrytkov @ Dec 21 2007, 20:59)

Список в студию!
Не надо списков - когда кто-пишет, что "на ARMе не отзываються " .... или подобные "диагнозы", то список ни сном ни духом.
Кроме того надписи с наклеек ничего не значат - под одинаковами наклейками могут быть самые разные начинки от партии к партии.
hsx_Vlad
Dec 21 2007, 19:48
Цитата(zltigo @ Dec 21 2007, 22:22)

Не надо списков - когда кто-пишет, что "на ARMе не отзываються " .... или подобные "диагнозы"
Чего к словам придираться, на команды CMD9 и CMD10 не меняют 11 байт SD Kingston и Panasonic, SD samsung и MMC Kingston работают нормально. В чем может быть причина?
zltigo
Dec 21 2007, 20:10
Цитата(hsx_Vlad @ Dec 21 2007, 21:48)

Чего к словам придираться,
Если эти слова ничего не значили, то тогда их просто не надо было произносить :-E. И не помещать вопрос в раздел ARM.
Цитата
на команды CMD9 и CMD10 не меняют 11 байт
Это на каком языке написано?
Эти команды ничего не меняют - они предназначены для считывания 16байтовых (не 11, а 16(0x11) байт ) информационных блоков. При этом, как всегда должны отрабатываться ожидания готовностей, контроль завершения исполнения команды перед тем, как считывать блок данных. При считывании блока, естествено, 100ms таймаут и контроль token.
Цитата
SD Kingston и Panasonic, SD samsung и MMC Kingston работают нормально. В чем может быть причина?
Работает на всех вышеперечисленных и многчисленных не перечисленных. В чем может быть причина?
hsx_Vlad
Dec 21 2007, 21:48
Написано на С, команды действительно 16-ти байтиные, а в случае успешного завершения 11-ый байт должен с 0xFF поменяться на 0x00. Общение осуществляется через DMA, поэтому проблем с таймоутом быть не может (проверка байта выполняется после соответствующего прирывания) однако всеравно не работает
zltigo
Dec 21 2007, 22:01
Цитата(hsx_Vlad @ Dec 21 2007, 23:48)

Написано на С, команды действительно 16-ти байтиные, а в случае успешного завершения 11-ый байт должен с 0xFF поменяться на 0x00. Общение осуществляется через DMA, поэтому проблем с таймоутом быть не может (проверка байта выполняется после соответствующего прирывания) однако всеравно не работает
Если кто-то поймет, что Вы написали, то возможно ответит.
P.S.
Волшебное DMA никоим образом не может обеспечить контроль за завершением операции карточкой и соответственно обеспечение ожиданий и таймаутов.
rv3dll(lex)
Dec 24 2007, 05:40
насчёт SPI режима не скажу - на всех раттах которые попадали в руки в SD режиме читались
hsx_Vlad
Dec 26 2007, 10:50
С причиной неработоспособности я разобрался, работают только те карточки, которые понимают протокол ММС, а где бы посмотреть, как общаться с карточками, которые его не понимают?
rv3dll(lex)
Dec 26 2007, 11:07
Цитата(hsx_Vlad @ Dec 26 2007, 13:50)

С причиной неработоспособности я разобрался, работают только те карточки, которые понимают протокол ММС, а где бы посмотреть, как общаться с карточками, которые его не понимают?
не понял??? sd и mmc имеют немного различный командный интерфейс различие незначительное
msalov
Dec 26 2007, 11:08
Цитата(hsx_Vlad @ Dec 26 2007, 12:50)

С причиной неработоспособности я разобрался, работают только те карточки, которые понимают протокол ММС, а где бы посмотреть, как общаться с карточками, которые его не понимают?
Предположение: по "протоколу SD"
hsx_Vlad
Dec 28 2007, 20:39
Цитата(gotty @ Dec 26 2007, 14:08)

Предположение: по "протоколу SD"
Это понятно, что по протоколу SD, где его спецификацию взять?
zltigo
Dec 28 2007, 21:38
Цитата(gotty @ Dec 26 2007, 13:08)

по "протоколу SD"
Перечисленные команды понимают и SD и MMC. Причина неработы, насколько можно понять, в попытке тупо через DMA вычитать 16 байт без ожидания готовности к передаче ожидаемых 16 байт.
rv3dll(lex)
Dec 29 2007, 05:19
у меня куча всего - но этого думаю достаточно
hsx_Vlad
Dec 30 2007, 21:22
С работоспособностью разобрался, задержка не причем, просто у одних карточек в 11-том быйте результат, а в других в 12-ом. Вот теперь такой вопрос, как определить какой байт смотреть?
zltigo
Dec 30 2007, 21:29
Цитата(hsx_Vlad @ Dec 30 2007, 23:22)

Вот теперь такой вопрос, как определить какой байт смотреть?
Повторяю последнй раз - дождитесь готовности и получите нормальные 16 байт, без
произвольного количества незначаших байт перед информационным блоком.
hsx_Vlad
Dec 30 2007, 21:40
насколько я знаю, дма генерит приерывание только в случае ошибки или вычитывания заданного количества байт

, т.е пока все требуемые байты не будут готовы, обработка дальше не пойдет
zltigo
Dec 30 2007, 21:48
Цитата(hsx_Vlad @ Dec 30 2007, 23:40)

насколько я знаю, дма ...
Еще не поняли? Повторяю - тупо использовать DMA для вычитывания блока нельзя, ибо размер его априори не известен.
Читаем по байтику, и
только получив правильный token вычитываем блок желаемого размера.
Код
//---------------------------------------------------------------------------
// Receive a data packet from MMC
//---------------------------------------------------------------------------
static int get_datablock( BYTE *dest, int count )
{
BYTE token;
ulong timer = xGetTimeout_ms( SD_RD_TIME_OUT ); // Wait for data packet in timeout
do
{ token = mmc_sendbyte( DUMMY_BYTE );
}
while( (token == 0xFF )&&( xIsTimeout( timer ) == FALSE ) );
if( token != DATA_TOKEN_17_18_24 )
return( FALSE ); // If not valid data token, retutn with error
mmc_receiveblock( dest, count );
mmc_sendbyte( 0xFF ); // Discard CRC
mmc_sendbyte( 0xFF ); // Discard CRC
return( TRUE ); // Return with success
}
hsx_Vlad
Dec 30 2007, 22:03
а что есть DATA_TOKEN_17_18_24?
zltigo
Dec 30 2007, 22:14
Цитата(hsx_Vlad @ Dec 31 2007, 00:03)

а что есть DATA_TOKEN_17_18_24?
А документ почитать?
Код
// Time ote definition for SD Read Time out ~100msec, Write Time out ~250ms
#define SD_RD_TIME_OUT 100
#define SD_WR_TIME_OUT 250
//
#define R1_OK 0x00
#define R1_IDLE_STATE 0x01
#define R1_ERASE_RST 0x02
#define R1_ILLEGAL_CMD 0x04
#define R1_CRC_ERROR 0x08
#define R1_ERASE_ERROR 0x10
#define R1_ADD_ERROR 0x20
#define R1_PARAM_ERROR 0x40
#define R1_NOTVALID 0x80
#define R1_NOTRESPONCE 0xFF
#define DUMMY_BYTE 0xFF
#define DATA_TOKEN_17 0xFE
#define DATA_TOKEN_18 DATA_TOKEN_17
#define DATA_TOKEN_24 DATA_TOKEN_17
#define DATA_TOKEN_17_18_24 DATA_TOKEN_17
#define DATA_TOKEN_25 0xFC
#define DATA_TOKEN_25_STOP 0xFD
#define DATA_TOKEN_ERROR 0x1F
#define DATA_RESP_MASK 0x1F
#define DATA_RESP_ACCEPT 0x05
#define DATA_RESP_CRC_ERR 0x0B
#define DATA_RESP_WR_ERR 0x0D
hsx_Vlad
Dec 31 2007, 11:05
Спасибо, но проблема чуть не в этом. Часть вычитывающая блок у меня работает нормально.
static DWORD MMC_read_block (u8 cmd, DWORD arg, u8 *buf, DWORD len)
{
DWORD res = CARD_ERROR;
DWORD i, k, indx;
u8 constval = 0xFF;
k = 0;
i = 0;
res = CARD_ERROR;
sd_att = SD_MAX_ATT;
do
{
SD_SELECT_CARD;
cmd_buf[0] = 0xFF;
cmd_buf[1] = 0xFF;
cmd_buf[2] = 0xFF;
cmd_buf[3] = 0xFF;
cmd_buf[4] = cmd;
cmd_buf[5] = (arg >> 24);
cmd_buf[6] = (arg >> 16);
cmd_buf[7] = (arg >> 8);
cmd_buf[8] = (arg);
cmd_buf[9] = 0xFF;
cmd_buf[10] = 0xFF;
cmd_buf[11] = 0xFF;
cmd_buf[12] = 0xFF; // Cb_end, Cb_transfer_err функции изменяющие значение ssp_flgs
ssp_flgs = 0; // Устанавливается в прерывании DMA в значения SSP_DONE или SSP_TX_ERR
Start_dma_read_from_SSPSD(cmd_buf, 13, Cb_end, Cb_transfer_err); // После этого чтения в буфере
Start_dma_write_to_SSPSD(cmd_buf, 13, 0, Cb_transfer_err); // 11 байт должен стать равным 0 если все нормально
while ( (ssp_flgs&(SSP_DONE|SSP_TX_ERR))==0 ); // количество данных, которые необходимо прочитать извесны 13, а становиться либо 11 либо 12
if(ssp_flgs&SSP_TX_ERR ) goto exit__;
if ( ((cmd_buf[11] & 0x80)==0) || ((cmd_buf[12] & 0x80)==0))
{
if(cmd_buf[11]!=0 && cmd_buf[12]!=0)
{
res = cmd_buf[i];
goto exit__;
}
sd_ratt = SD_MAX_RATT;
do
{
ssp_flgs = 0;
Start_dma_read_from_SSPSD(cmd_buf, READ_WAIT_LEN, Cb_end, Cb_transfer_err);
Start_dma_write_const_to_SSPSD(&constval, READ_WAIT_LEN, 0, Cb_transfer_err);
while((ssp_flgs&(SSP_DONE|SSP_TX_ERR))==0 );
if(ssp_flgs&SSP_TX_ERR ) goto exit__;
for ( i=0;i<READ_WAIT_LEN;i++ )
{
if ( cmd_buf[i] == 0xFE )
{
k = i + 1;
break;
}
}
if ( cmd_buf[i] == 0xFE ) break;
sd_ratt--;
if ( sd_ratt==0 ) goto exit_att__;
}
while ( 1 );
indx = 0;
for ( i=k;i<READ_WAIT_LEN;i++ )
{
buf[indx++] = cmd_buf[i];
if ( indx==len ) break;
}
if ( indx!=len )
{
ssp_flgs = 0;
Start_dma_read_from_SSPSD(&buf[indx], len - indx, Cb_end, Cb_transfer_err);
Start_dma_write_const_to_SSPSD(&constval, len - indx, 0, Cb_transfer_err);
while ( (ssp_flgs&(SSP_DONE|SSP_TX_ERR))==0 );
if ( ssp_flgs&SSP_TX_ERR) goto exit__;
}
ssp_flgs = 0;
Start_dma_read_from_SSPSD(cmd_buf, 3, Cb_end, Cb_transfer_err);
Start_dma_write_const_to_SSPSD(&constval, 3, 0, Cb_transfer_err);
while ( (ssp_flgs&(SSP_DONE|SSP_TX_ERR))==0 );
if ( ssp_flgs&SSP_TX_ERR ) goto exit__;
res = CARD_OK;
goto exit__;
}
exit_att__: SD_UNSELECT_CARD;
sd_att--;
}
while ( sd_att!=0 );
exit__: SD_UNSELECT_CARD;
return res;
}
zltigo
Dec 31 2007, 12:26
Цитата(hsx_Vlad @ Dec 31 2007, 13:05)

Часть вычитывающая блок у меня работает нормально.
Нет.
В качестве Новогоднего подарка еще два кусочка исходников опять таки с таймаутами и готовностями

кои с ..... ну, скажем, упорством достойным лучшего применения Вы пытаетесь игнорировать.
Код
//---------------------------------------------------------------------------
// Send a command to MMC
//---------------------------------------------------------------------------
static BYTE send_cmd( BYTE cmd, DWORD arg )
{
BYTE nn;
BYTE res;
if( wait_ready() )
return( 0x8F );
// Send command packet
mmc_sendbyte( cmd ); // Command
mmc_sendbyte( arg >> 24 ); // Argument[31..24]
mmc_sendbyte( arg >> 16 ); // Argument[23..16]
mmc_sendbyte( arg >> 8 ); // Argument[15...8]
mmc_sendbyte( arg ); // Argument[7....0]
if( cmd == CMD0_RESET )
nn = 0x95; // CRC for CMD0 (0)
else if( cmd == CMD8_IF_V2 )
nn = 0x87; // CRC for CMD8 (0x1AA)
else
nn = 0x00;
mmc_sendbyte( nn );
// Receive command response
if( cmd == CMD12_STOP_TX )
mmc_sendbyte( 0xFF ); // Skip a stuff byte when stop reading
// Wait for a valid response in timeout of 10 attempts
nn = 10;
do
{ res = mmc_sendbyte( 0xFF );
}
while( ( res & R1_NOTVALID )&&( --nn ) );
return( res ); // Return with the response value
}
//---------------------------------------------------------------------------
// Wait for card ready
//---------------------------------------------------------------------------
static int wait_ready(void)
{
// Wait for ready in timeout
ulong timer = xGetTimeout_ms( SD_READY_TIME_OUT );
BYTE ret;
mmc_sendbyte( 0xFF );
do
{ ret = mmc_sendbyte( 0xFF );
if( ret == 0xFF )
return( 0 );
}
while( xIsTimeout( timer ) == FALSE );
return( 1 );
}
Moderator:
Воздержитесь от постов длиных (воспользуйтесь возможностями приложений) невнятных неформатированных (ознакомьтесь с возможностями тэгов) кусков исходных текстов.
hsx_Vlad
Dec 31 2007, 13:21
Спасибо, вот это меня как раз и интерисовало, получается что место нахождения ответа на команду тоже плавающее.
zltigo
Dec 31 2007, 14:16
Цитата(hsx_Vlad @ Dec 31 2007, 15:21)

получается что место нахождения ответа на команду тоже плавающее.
Естественно и документировано. Естественно, потому, что в карточке свой контроллер и самая разнообразная по быстродействию начинка. Попытки тупо всегда и везде использовать блочный DMA приводят к кривизне. Используйте DMA в эквиваленте mmc_receiveblock() - сие будет разумно и правильно. Остальное по байтикам. Даже притягивание за уши посылки, например, одним блоком команды прведет только к дополнительным потерям времени на формирование буфера и затратам памяти для самого буфера.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.