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

Вот теперь такой вопрос, как определить какой байт смотреть?

Повторяю последнй раз - дождитесь готовности и получите нормальные 16 байт, без произвольного количества незначаших байт перед информационным блоком.

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


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

насколько я знаю, дма генерит приерывание только в случае ошибки или вычитывания заданного количества байт :(, т.е пока все требуемые байты не будут готовы, обработка дальше не пойдет

Изменено пользователем hsx_Vlad

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


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

насколько я знаю, дма ...

Еще не поняли? Повторяю - тупо использовать 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
}

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


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

а что есть 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

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


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

Спасибо, но проблема чуть не в этом. Часть вычитывающая блок у меня работает нормально.

 

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;

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 == 0xFE )

{

k = i + 1;

break;

}

}

if ( cmd_buf == 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;

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;

}

Изменено пользователем hsx_Vlad

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


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

Часть вычитывающая блок у меня работает нормально.

Нет.

 

В качестве Новогоднего подарка еще два кусочка исходников опять таки с таймаутами и готовностями :) кои с ..... ну, скажем, упорством достойным лучшего применения Вы пытаетесь игнорировать.

 

//---------------------------------------------------------------------------
// 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:

Воздержитесь от постов длиных (воспользуйтесь возможностями приложений) невнятных неформатированных (ознакомьтесь с возможностями тэгов) кусков исходных текстов.

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


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

Спасибо, вот это меня как раз и интерисовало, получается что место нахождения ответа на команду тоже плавающее.

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


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

получается что место нахождения ответа на команду тоже плавающее.

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

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...