реклама на сайте
подробности

 
 
> microSD SDIO, Помогите начать
MiklPolikov
сообщение Oct 30 2014, 17:11
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Коллеги, добрый день.

Пытаюсь подключить microSD карту к интерфейсу SDIO STM32L151RDT
Возникла проблема с чтением.

Инициализация проходит.
На CMD2 , CMD3 карта отвечает.
Посылаю CMD7, получаю ответ с верным CRC
Посылаю CMD17 , получаю ответ с верным CRC
Перевожу SDIO в режим чтения. Он выдаёт ~40 клоков , после чего выставляет бит ошибки "не получен старт бит" .

Вопрос 1: правильно ли я понимаю, что "старт бит" должен быть выдан картой одновременной по всем линиям D0-D3 ?

Вопрос 2: Вижу по осциллографу, что на линии D0 во время пачки клоков что-то есть, на остальных высокий уровень(они все подтянуты к питанию) .
Можно ли предположить, что карта в SPI режиме ?

Вопрос 3 : Если карта на самом деле в SPI режиме, то как она должна попасть в SDIO режим ? Если это происходит путём подачи CMD0 в то время как линия DAT3/CS в высоком уровне, то это условие у меня выполняется, т.к. линии D0-D3 подтянуты к питанию.

Вопрос 4 : Правильно ли я понимаю алгоритм чтения в режиме SDIO ? Проинициализировались - > CMD7 c верным RCA -> CMD17 с одресом -> и карта начинает выдавать данные.
Не совсем понятно, надо ли в ответах на CMD7 CMD17 проверять ещё что-то, помимо того что они просто получены ? "карта начинает выдавать данные" - в ответ на клоки SDIO контроллера ? И перед данными выдаёт старт-бит ?

Заранее спасибо !


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
4 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 49)
MiklPolikov
сообщение Oct 30 2014, 18:36
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



И ещё, ни как не могу понять, что именно делает CMD7 . В документации написано "SELECT / DESELECT CARD". Ну а как понять, выбрана оказалась карта после очередной CMD7 , или наоборот ? Отпарвляю CMD7 , получаю ответ. Все последующие отправки-ответа нет.


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Nov 1 2014, 17:34
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Разобрался. Выкладываю свой максимально простой код. Надеюсь что кому-нибудь поможет. Кое-где есть функции операционной системы, ожидающие прерывания от выставления флагов в регистре состояния SDIO. Их легко заменить простой проверка этого регистра в бесконечном цикле, прерывание при этом надо отключить.

Ноги процессора настраиваются так. Принципиально, что на всех подтяжка к +

////////////////////
void SD_INTERFACE_INIT(void)
{
//включаем тактирование порта
RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
RCC->AHBLPENR|=RCC_AHBLPENR_GPIOCLPEN;

RCC->AHBENR |= RCC_AHBENR_GPIODEN;
RCC->AHBLPENR|=RCC_AHBLPENR_GPIODLPEN;

__dsb(15);

//скорость порта максимальная
GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8|GPIO_OSPEEDER_OSPEEDR9|GPIO_OSPEEDER_OSPEEDR10|GPIO_OSPEE
DER_OSPEEDR11| GPIO_OSPEEDER_OSPEEDR12;
GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR2;

//SD1 SDIO
GPIOC->MODER &= ~GPIO_MODER_MODER8;
GPIOC->MODER |= GPIO_MODER_MODER8_1;
GPIOC->MODER &= ~GPIO_MODER_MODER9;
GPIOC->MODER |= GPIO_MODER_MODER9_1;
GPIOC->MODER &= ~GPIO_MODER_MODER10;
GPIOC->MODER |= GPIO_MODER_MODER10_1;
GPIOC->MODER &= ~GPIO_MODER_MODER11;
GPIOC->MODER |= GPIO_MODER_MODER11_1;
GPIOC->MODER &= ~GPIO_MODER_MODER12;
GPIOC->MODER |= GPIO_MODER_MODER12_1;

GPIOD->MODER &= ~GPIO_MODER_MODER2;
GPIOD->MODER |= GPIO_MODER_MODER2_1;

GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR8;
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR8_0;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR9;
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR9_0;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR10;
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR10_0;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR11;
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR11_0;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR12;
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR12_0;

GPIOD->PUPDR &=~ GPIO_PUPDR_PUPDR2;
GPIOD->PUPDR |= GPIO_PUPDR_PUPDR2_0;

GPIOC->AFR[1]|=(12<<0);
GPIOC->AFR[1]|=(12<<4);
GPIOC->AFR[1]|=(12<<8);
GPIOC->AFR[1]|=(12<<12);
GPIOC->AFR[1]|=(12<<16);

GPIOD->AFR[0]|=(12<<8);
}

SDIO настраивается так. Включены прерывания по всем важным флагам по итогам передачи команды и данных.
PLL настроен так, что частота процессора 32МГц, промежуточная частота PLL, от которой тактируется SDIO, 48МГц


//////////////////////////настраиваем SDIO для SD ///////////////////////////////////////////////////////
void SD_SDIO_INIT(void)
{
RCC->APB2ENR|=RCC_APB2ENR_SDIOEN; // включаем тактирование
RCC->APB2LPENR|=RCC_APB2LPENR_SDIOLPEN;

RCC->APB2RSTR|=RCC_APB2RSTR_SDIORST;
RCC->APB2RSTR&=~RCC_APB2RSTR_SDIORST; //сброс настроек

SDIO->CLKCR|=SDIO_CLKCR_HWFC_EN; //HW Flow Control is enabled
SDIO->CLKCR|=SDIO_CLKCR_WIDBUS_0; // 4-wide bus mode: SDIO_D[3:0] used ++
SDIO->CLKCR|=SDIO_CLKCR_PWRSAV; //SDIO_CK is only enabled when the bus is active
SDIO->CLKCR|=SDIO_CLKCR_CLKEN; //SDIO_CK is enabled ++


SDIO->DCTRL|=SDIO_DCTRL_SDIOEN;
SDIO->DCTRL|=SDIO_DCTRL_RWMOD; //Read Wait control using SDIO_CK ///Непонятно, что это
SDIO->DCTRL|=SDIO_DCTRL_DBLOCKSIZE_0 | SDIO_DCTRL_DBLOCKSIZE_3; // размер блока 512 ++
SDIO->DCTRL|=SDIO_DCTRL_DMAEN; //DMA enabled. ++

///////включаем прерывания
SDIO->MASK|=SDIO_MASK_STBITERRIE;
SDIO->MASK|=SDIO_MASK_DATAENDIE;
SDIO->MASK|=SDIO_MASK_CMDRENDIE;
SDIO->MASK|=SDIO_MASK_DTIMEOUTIE;
SDIO->MASK|=SDIO_MASK_CTIMEOUTIE;
SDIO->MASK|=SDIO_MASK_DCRCFAILIE;
SDIO->MASK|=SDIO_MASK_CCRCFAILIE;
SDIO->MASK|=SDIO_MASK_CMDSENTIE;

NVIC_SetPriority(SDIO_IRQn, 11);
NVIC_EnableIRQ(SDIO_IRQn);

SDIO->POWER|=SDIO_POWER_PWRCTRL ; //Включаем SDIO

}

функция передачи CMD команды. После начала передачи функция ждёт прерывания от выставления флагов в SDIO STA . У меня операционка, но её можно выкинуть, заменив просто поллингом регистра STA, или передачей флага из прерывания через глобальную переменную.

////////////////////////////////////////
__inline char SEND_CMD(char sd_n, unsigned char cmd, unsigned long int argument, unsigned char response_type, unsigned int* ansver )
{
unsigned int SDIO_CMD_MASK;
EventBits_t SDIO_STA_MASK;

//Clear the Command Flags
SDIO->ICR=0xFFFFFFFF; //(SDIO_STA_CCRCFAIL | SDIO_STA_CTIMEOUT | SDIO_STA_CMDREND | SDIO_STA_CMDSENT);
SDIO->ARG=argument; //First adjust the argument (because I will immediately enable CPSM next)
SDIO_CMD_MASK=cmd; //The last argument is to enable CSPM
SDIO_CMD_MASK |=SDIO_CMD_CPSMEN; //The last argument is to enable CSPM
switch(response_type){
case RESPONSE_0_BIT :
SDIO_CMD_MASK &=~SDIO_CMD_WAITRESP_0;
SDIO_CMD_MASK &=~SDIO_CMD_WAITRESP_1;
break;
case RESPONSE_48_BIT :
SDIO_CMD_MASK |=SDIO_CMD_WAITRESP_0;
SDIO_CMD_MASK &=~SDIO_CMD_WAITRESP_1;
break;
case RESPONSE_136_BIT :
SDIO_CMD_MASK |=SDIO_CMD_WAITRESP_0;
SDIO_CMD_MASK |=SDIO_CMD_WAITRESP_1;
default :
SDIO_CMD_MASK |=SDIO_CMD_WAITRESP_0;
SDIO_CMD_MASK |=SDIO_CMD_WAITRESP_1;
}

xEventGroupClearBits(x_SDIO_Transmit_EventGroup,0xFFFFFFF);
SDIO->CMD=SDIO_CMD_MASK; //запускаем передачу команды

if (response_type==RESPONSE_0_BIT)
{
SDIO_STA_MASK=xEventGroupWaitBits(x_SDIO_Transmit_EventGroup, SDIO_STA_CMDSENT | SDIO_STA_CTIMEOUT, pdTRUE, pdFALSE, 5);
if(SDIO_STA_MASK & SDIO_STA_CTIMEOUT)
return SD_ERROR;
return SD_OK;
}
else //SHRESP or LNRESP or R3RESP
{
SDIO_STA_MASK=xEventGroupWaitBits(x_SDIO_Transmit_EventGroup, SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL, pdTRUE, pdFALSE, 5);

if(SDIO_STA_MASK & SDIO_STA_CTIMEOUT)
return SD_ERROR;
if(SDIO_STA_MASK& SDIO_STA_CCRCFAIL)
{
if(cmd==CMD41)
{
ansver[0]=SDIO->RESP1;
ansver[1]=SDIO->RESP2;
return SD_OK;
}
else
return SD_ERROR;
}
if(SDIO_STA_MASK & SDIO_STA_CMDREND)
{
ansver[0]=SDIO->RESP1;
ansver[1]=SDIO->RESP2;
if(response_type==RESPONSE_136_BIT)
{
ansver[2]=SDIO->RESP3;
ansver[3]=SDIO->RESP4;
}
return SD_OK;
}
}
return SD_ERROR;
}


Функция настройки DMA для передачи SDIO <> буфер памяти
///////////////////////////////////////////////////////////////////////////////////
void SD_DMA_INIT(void)
{
RCC->AHBENR|=RCC_AHBENR_DMA2EN; //включили тактирование DMA
RCC->AHBLPENR|=RCC_AHBLPENR_DMA2LPEN;

RCC->AHBRSTR&=~RCC_AHBRSTR_DMA2RST;//перестаём сбрасывать настройки DMA

//передача и приём
DMA2_Channel4->CCR&=~DMA_CCR4_EN;// выключили канал
DMA2_Channel4->CCR|=DMA_CCR4_TCIE;// прерывание при конце передачи
DMA2_Channel4->CCR|=DMA_CCR4_MSIZE_1; //размер памяти 32
DMA2_Channel4->CCR|=DMA_CCR4_PSIZE_1; //размер периферии 32
}
}

Функции запуска DMA для чтения и для записи
///////////////////////////////запускаем чтение SD по DMA /////////////////////////////////
void SD_DMA_START_READ(char sd_n, unsigned char *p_buf_r, int data_size)
{
// "периферия" -откуда берутся данные
// "память" -куда идёт данные
if(sd_n==SD1)
{
DMA2_Channel4->CCR&=~DMA_CCR4_EN; // канал приёма и передачи

DMA2_Channel4->CNDTR=data_size/4; //т.к. data_size в байтах, а размер регистра 32 байта
DMA2_Channel4->CMAR=(uint32_t)p_buf_r; // сюда идут данные
DMA2_Channel4->CPAR=(uint32_t)(&SDIO->FIFO); // отсюда идут данные
DMA2_Channel4->CCR|=DMA_CCR4_MINC;
DMA2_Channel4->CCR &=~ DMA_CCR4_PINC;


DMA2_Channel4->CCR|=DMA_CCR4_EN;

}

}

///////////////////////////////запускаем запись в SD по DMA /////////////////////////////////
void SD_DMA_START_WRITE(char sd_n, unsigned char *p_buf_w, int data_size)
{
// "периферия" -откуда берутся данные
// "память" -куда идёт данные

DMA2_Channel4->CCR&=~DMA_CCR4_EN; // канал приёма и передачи

DMA2_Channel4->CNDTR=data_size/4; //т.к. data_size в байтах, а размер регистра 32 байта
DMA2_Channel4->CPAR=(uint32_t)p_buf_w; // сюда идут данные
DMA2_Channel4->CMAR=(uint32_t)(&SDIO->FIFO); // отсюда идут данные
DMA2_Channel4->CCR|=DMA_CCR4_PINC;
DMA2_Channel4->CCR&=~DMA_CCR4_MINC;

DMA2_Channel4->CCR|=DMA_CCR4_EN;
}

Инициализация карты. Работает только на картах больше 2Гб. См. комментарии.
///// Как это работает написано в документе Part_1_Physical_Layer_Simplified_Specification_Ver3.01_Final_100518-1.pdf страница 115
char SD_initialize (char sd_n)
{
unsigned int cmd_ansver[4];
char result;
unsigned long int time;
unsigned int C_SIZE;

time=xTaskGetTickCount()+(2000/portTICK_RATE_MS);

SD_SCK_DIV_60(sd_n)

SEND_CMD(sd_n, CMD0,0,RESPONSE_0_BIT,&cmd_ansver[0]);
SEND_CMD(sd_n, CMD0,0,RESPONSE_0_BIT,&cmd_ansver[0]); //почему то c одним CMD0 не работает
result=SEND_CMD(sd_n, CMD8,0x1AA,RESPONSE_48_BIT,&cmd_ansver[0]);
if(result==SD_OK) //карта ответила на CMD8
{
if((cmd_ansver[0] & 0x1FF)!=0x1AA) //контрольная цифра не верна
{
result= FR_DISK_ERR;
}
else
{
while(1)
{
result=SEND_CMD(sd_n, CMD55,0,RESPONSE_48_BIT,&cmd_ansver[0]);
if(result==SD_OK)
result=SEND_CMD(sd_n, CMD41, /*(1<<31)*/ 0x80000000 |(1<<20)|(1<<30)|(1<<28) ,RESPONSE_48_BIT,&cmd_ansver[0]); //|(1<<28) включает макс.скорость
if(result==SD_OK)
{
if((cmd_ansver[0] & /*(1<<31)*/ 0x80000000)!=0) //инициализация пройдена
{
if((cmd_ansver[0] & (1<<30))!=0) //CCS=1
CardType[sd_n]=SDHC_SDXC;
else //CCS=0
CardType[sd_n]=SDSC;

result=SEND_CMD(sd_n, CMD2,0,RESPONSE_136_BIT,&cmd_ansver[0]);
if(result==SD_OK)
result=SEND_CMD(sd_n, CMD3,0,RESPONSE_48_BIT,&cmd_ansver[0]);
if(result==SD_OK)
sd_RCA[sd_n]=(cmd_ansver[0])>>16;
break;
}
}
else
{
result= FR_DISK_ERR;
break;
}

if(xTaskGetTickCount()>time)
{
result= FR_DISK_ERR;
break;
}
}
}
}
else //карта не ответила на CMD8
{
while(1)
{
result=SEND_CMD(sd_n, CMD55,0,RESPONSE_48_BIT,&cmd_ansver[0]);
if(result==SD_OK)
result=SEND_CMD(sd_n, CMD41, /*(1<<31)*/ 0x80000000 |(1<<20)|(1<<28) ,RESPONSE_48_BIT,&cmd_ansver[0]);
if(result==SD_OK)
{
if((cmd_ansver[0] & /*(1<<31)*/ 0x80000000)!=0) //инициализация пройдена
{
CardType[sd_n]=SDSC;
result =FR_OK;
break;
}
}
else
{
result= FR_DISK_ERR;
break;
}

if(xTaskGetTickCount()>time)
{
result= FR_DISK_ERR;
break;
}
}
}

//Включаем частоту шины в соответствии с классом скорости карты. Надо бы сделать получение класса скорости от карты.
SD_SCK_DIV_8(sd_n)

//Узнаём количество секторов на карте
if(result==SD_OK)
result=SEND_CMD(sd_n, CMD9, sd_RCA[sd_n]<<16, RESPONSE_136_BIT, &cmd_ansver[0]);
if(CardType[sd_n]==SDHC_SDXC)
{
C_SIZE =((cmd_ansver[1] & 0x1F)<<17) + ((cmd_ansver[2] & 0xFFFF0000)>>16); //биты 69-48
sd_total_sectors[sd_n]=C_SIZE*1024;
}
else
{
sd_total_sectors[sd_n]=0; //тут надо бы сделать обработку старых карт
}

if(result==SD_OK)
result=SEND_CMD(sd_n, CMD7, sd_RCA[sd_n]<<16, RESPONSE_48_BIT, &cmd_ansver[0]);
if(result==SD_OK)
result=SEND_CMD(sd_n, CMD55, sd_RCA[sd_n]<<16 , RESPONSE_48_BIT, &cmd_ansver[0]);
if(result==SD_OK)
result=SEND_CMD(sd_n, CMD6, 0x02, RESPONSE_48_BIT, &cmd_ansver[0]); //выбираем шину 4 бита


return result;
}

Функция чтения
/////////////////////////////////////////////////////////////////////
__inline DRESULT TRY_disk_read (
BYTE Drive, /* Physical drive number */
BYTE* pBuffer, /* Pointer to the read data buffer */
DWORD SectorNumber, /* Start sector number */
BYTE SectorCount /* Number of sectros to read */
)
{
unsigned long int sd_adress,number_of_block;
unsigned long int i;
unsigned char result;
char sd_n =Drive;
EventBits_t SDIO_STA_MASK;

unsigned int cmd_ansver[4];

if(CardType[sd_n]==SDHC_SDXC)
sd_adress=SectorNumber;
else
sd_adress=SectorNumber*0x200;

number_of_block=SectorCount;

for(i=0;i<number_of_block;i++)
{
result=SEND_CMD(sd_n, CMD17, sd_adress+(i*512), RESPONSE_48_BIT, &cmd_ansver[0]);
if(result!=SD_OK)
{
ADD_EVENT_MESSAGE_SDx(sd_n,"#!!! ERROR: TRY_disk_read: CMD18: Ошибка 2#");
return RES_ERROR;
}

//xSemaphoreTake(x_SD_Multi_Transmit_Complite[sd_n],0);//
xEventGroupClearBits(x_SDIO_Transmit_EventGroup,0xFFFFFFF);
SD_DMA_START_READ(sd_n,pBuffer+(i*512),512);

SDIO->ICR=0xFFFFFFFF;

SDIO->DTIMER= 0xffffff;
SDIO->DLEN=512;

SDIO->DCTRL=SDIO_DCTRL_DBLOCKSIZE_0 | SDIO_DCTRL_DBLOCKSIZE_3; // размер блока 512
SDIO->DCTRL|=SDIO_DCTRL_DMAEN; //DMA enabled.
SDIO->DCTRL|=SDIO_DCTRL_DTDIR; //Direction. //направление передачи из дарты в процессор
SDIO->DCTRL|=SDIO_DCTRL_RWSTART; //
SDIO->DCTRL|=SDIO_DCTRL_DTEN; //DPSM is enabled //запускаем передачу данных

//Ждём выставления флагов в прерывании. По результатам судим о успехе/не успехе передачи
SDIO_STA_MASK=xEventGroupWaitBits(x_SDIO_Transmit_EventGroup, SDIO_STA_DBCKEND | SDIO_STA_STBITERR /*| SDIO_STA_DATAEND */ | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL, pdTRUE, pdFALSE, 10);
if(SDIO_STA_MASK & SDIO_STA_CTIMEOUT)
return RES_ERROR;

if(SDIO_STA_MASK & (SDIO_STA_STBITERR | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL ))
return RES_ERROR;
}
return RES_OK;
}

И очень похожая функция записи
/////////////////////////////////////////////////////////////////////
__inline DRESULT TRY_disk_write(
BYTE Drive, /* Physical drive number */
unsigned char* pBuffer, /* Pointer to the read data buffer */
DWORD SectorNumber, /* Start sector number */
BYTE SectorCount /* Number of sectros to read */

)
{
char sd_n=Drive;
char result;
unsigned long int i;
unsigned long int sd_adress,number_of_block;
EventBits_t SDIO_STA_MASK;

unsigned int cmd_ansver[4];

if(CardType[sd_n]==SDHC_SDXC)
sd_adress=SectorNumber;
else
sd_adress=SectorNumber*0x200;

number_of_block=SectorCount;

for(i=0;i<number_of_block;i++)
{
result=SEND_CMD(sd_n, CMD24, sd_adress+(i*512), RESPONSE_48_BIT, &cmd_ansver[0]);
if(result!=SD_OK)
{
ADD_EVENT_MESSAGE_SDx(sd_n,"#!!! ERROR: TRY_disk_write: CMD24: Ошибка 2#");
return RES_ERROR;
}

xEventGroupClearBits(x_SDIO_Transmit_EventGroup,0xFFFFFFF);
SD_DMA_START_WRITE(sd_n,pBuffer+(i*512),512);

SDIO->ICR=0xFFFFFFFF;

SDIO->DTIMER= 0xffffff;
SDIO->DLEN=512;

SDIO->DCTRL=SDIO_DCTRL_DBLOCKSIZE_0 | SDIO_DCTRL_DBLOCKSIZE_3; // размер блока 512
SDIO->DCTRL|=SDIO_DCTRL_DMAEN; //DMA enabled.
SDIO->DCTRL &=~ SDIO_DCTRL_DTDIR; //Direction. //направление передачи из процессора в карту
SDIO->DCTRL|=SDIO_DCTRL_DTEN; //DPSM is enabled //запускаем передачу

SDIO_STA_MASK=xEventGroupWaitBits(x_SDIO_Transmit_EventGroup, SDIO_STA_DBCKEND | SDIO_STA_STBITERR /*| SDIO_STA_DATAEND */ | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL, pdTRUE, pdFALSE, 10);
if(SDIO_STA_MASK & SDIO_STA_CTIMEOUT)
return RES_ERROR;

if(SDIO_STA_MASK & (SDIO_STA_STBITERR | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL ))
return RES_ERROR;
}
return RES_OK;

}


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 1 2014, 18:49
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Аминьsm.gif
Кстати, у вас в SEND_CMD() не хватает break-а в ветке case RESPONSE_136_BIT. Просто глаз зацепился.
Ну и в тэги [сode]/[сodebox] бы код оформить...


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Nov 1 2014, 21:33
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(AHTOXA @ Nov 1 2014, 22:49) *
Ну и в тэги [сode]/[сodebox] бы код оформить...


Сколько раз пробовал, у меня код в этих тегах разъезжается. Перед каждой строчкой появляется непредсказуемое количество пробелов, причём редактировать их количество так что бы становилось ровно не получается.


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Nov 4 2014, 02:41
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Подскажите, какой командой в режиме SDIO узнают, готова ли карта для приёма следующего блока данных ? При записи нескольких блоков подряд происходит ошибка, а если вставить задержки то всё хорошо.
И то же самое при мультиблочной записи(CMD25) . На втором блоке SDIO выставляет флаг ошибки STA DCRCFAIL . А если блоки разделить задержками, то всё хорошо. Что на самом деле нужно делать между отправками блоков в мультиблочной записи ?


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 4 2014, 06:18
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Перед отправкой команд CMD24/CMD25 нужно дожидаться готовности карты.
Для этого читать статус (CMD13_SEND_STATUS), и проверять бит READY_FOR_DATA.
После этого можно писать. (Между блоками в мультиблочной записи проверять готовность не нужно. По крайней мере, если пишем через DMA).
Точно так же нужно проверять готовность перед командами чтения (CMD17/CMD18).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Nov 4 2014, 15:18
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(AHTOXA @ Nov 4 2014, 10:18) *
Перед отправкой команд CMD24/CMD25 нужно дожидаться готовности карты.
Для этого читать статус (CMD13_SEND_STATUS), и проверять бит READY_FOR_DATA.
После этого можно писать. (Между блоками в мультиблочной записи проверять готовность не нужно. По крайней мере, если пишем через DMA).
Точно так же нужно проверять готовность перед командами чтения (CMD17/CMD18).


Спасибо.
У меня проблема исчезла, после того как вставил CMD13 с проверкой бита READY_FOR_DATA между блоками в мультиблочной передаче(CMD25). Перед CMD25 проверка READY_FOR_DATA не помогла.


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Nov 4 2014, 15:18
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(AHTOXA @ Nov 4 2014, 10:18) *
Перед отправкой команд CMD24/CMD25 нужно дожидаться готовности карты.
Для этого читать статус (CMD13_SEND_STATUS), и проверять бит READY_FOR_DATA.
После этого можно писать. (Между блоками в мультиблочной записи проверять готовность не нужно. По крайней мере, если пишем через DMA).
Точно так же нужно проверять готовность перед командами чтения (CMD17/CMD18).


Спасибо.
У меня проблема исчезла, после того как вставил CMD13 с проверкой бита READY_FOR_DATA между блоками в мультиблочной передаче(CMD25). Перед CMD25 проверка READY_FOR_DATA не помогла.


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 4 2014, 17:49
Сообщение #10


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Я что-то не понял. Вы что, блоки отправляете по одному? Так ведь вся суть команды CMD25 в том, что можно отправить сразу много блоков одной пачкой!
Допустим, у вас 4К данных. Вы ждёте готовности (CMD13), потом даёте команду CMD25, и натравливаете DMA на все свои 4К. И все 4К сразу и передаются.
Где здесь "между блоками"?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Nov 4 2014, 19:13
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(AHTOXA @ Nov 4 2014, 21:49) *
Где здесь "между блоками"?


Почему-то я был уверен, что блоки можно отправлять только по одному, и после каждого надо ждать выставления флагов в SDIO STA . Сейчас попробовал все разом, и действительно, заработало !


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 27 2015, 19:42
Сообщение #12


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Нет ли у кого-нибудь информации о том, в каких типах карт допустима невыравненная мультиблоковая запись? На некоторых SDHC я проверял - работает. Пока неработающую не встретил. А т.к. винда злостно форматирует кластеры на невыравненных адресах, то разбивать 4К кластер на 4+2+1+1 сектор записи вместо одной в 8 секторов - это непозволительная роскошь. Насколько я заметил, стыковка даже мультиблоков делается самой картой (SDHC) и только в момент ухода с какой-то внутренней грануляции карты возникает процесс записи и выдача BUSY. Вопрос насколько старые карты так умеют делать? MMC? SD ver1?

Цитата(AHTOXA @ Nov 4 2014, 10:18) *
... Между блоками в мультиблочной записи проверять готовность не нужно. ...

При невыравненном доступе - нужно. Прямо между блоками может 50 мс BUSY встрять.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Mar 27 2015, 19:50
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(GetSmart @ Mar 27 2015, 22:42) *
Нет ли у кого-нибудь информации о том, в каких типах карт допустима невыравненная мультиблоковая запись?


Не совсем понятно, что значит "невыровненная". Речь идёт о выравнивании адреса на 0x200 байт , или о чём-то ещё ?
И , ради любопытства, зачем Вам это ?


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 27 2015, 20:08
Сообщение #14


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Нееее. У SDHC передаётся сразу номер блока/сектора (т.н. сектор = 512 байт блок).

А невыровненная это когда по адресу блока допустим 0x0015 пишется блок длиной 0x003F блоков. Здесь уже и адрес и длина блока невыровненные. Но длина блока некратная степени двойки это я ещё не проверял. Но , думаю, на SDHC вполне может работать.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Mar 27 2015, 20:23
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(GetSmart @ Mar 27 2015, 23:08) *
по адресу блока допустим 0x0015 пишется блок длиной 0x003F блоков. Здесь уже и адрес и длина блока невыровненные.


Я давно и много работаю с самыми разными SD , но Ваших слов почему-то не понимаю.


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 30 2015, 19:03
Сообщение #16


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



ProductManualSDCardv2.2final.pdf

Раздел 5.5 Data Write.
Рисунок 5-5 Multiple Block Write Operation
На блок-схеме видно, что после CMD25 между любым блоком данных возможно появление BUSY.

По поводу грануляции SD-карт есть некоторое пояснение у Чена h__p://elm-chan.org/docs/mmc/mmc_e.html

Разве никто не делал лог появлений BUSY в мультисекторной записи? У меня на 8-гиговой возникали паузы после первого переданного блока данных в команде CMD25 и чтобы отправить остальные блоки приходится ждать пропадения BUSY. Причём грануляция появления BUSY в переводе на килобайты - от 16 КБ в начале файла коротких BUSY, и далее через грубо 8 раз грануляция увеличивается до 640 КБ и 45 мс BUSY. Карта по какой-то своей логике её меняет. Но блок, после которого формируется длинный BUSY сохраняется - после первого (видимо зависит от форматирования // кластерного сдвига // адреса в команде CMD25). В тесте CMD25 всегда была на 16 блоков.


Но я может быть перемудрил/преувеличил опасения по поводу "невыравненной мультиблоковой записи". Т.к. если в документе ProductManualSDCardv2.2final.pdf нет ограничений на выравнивание адреса, то видимо во всех SD-картах это изначально допускалось. И влияет невыровненность адреса (блока) только на момент формирования длинного BUSY.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 30 2015, 19:23
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Mar 30 2015, 22:03) *
Но я может быть перемудрил/преувеличил опасения по поводу "невыравненной мультиблоковой записи". Т.к. если в документе ProductManualSDCardv2.2final.pdf нет ограничений на выравнивание адреса, то видимо во всех SD-картах это изначально допускалось. И влияет невыровненность адреса (блока) только на момент формирования длинного BUSY.

Ограничений нет (и не было). Влияет, но для каждого типа карты влияние индивидуально, так что в конечном счете это не важно.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 30 2015, 19:35
Сообщение #18


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Что касаемо невыровненной записи, то за неё отвечают флаги WRITE_BLK_MISALIGN и WRITE_BL_PARTIAL в CSD.
Первый - определяет, допускает ли карта невыровненный начальный адрес блока, второй - допускает ли карта размер блока меньше чем 512.
Насколько я понял, первый роялит только для не-SDHC карт. (Потому что для SDHC карт не получится передать невыровненный адрес).

Что же до флага BUSY при мультиблоковой записи - не разу его не проверял, и не имел проблем. Возможно, с ним работает аппаратура SDIO контроллера.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 30 2015, 20:09
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(AHTOXA @ Mar 30 2015, 22:35) *
Насколько я понял, первый роялит только для не-SDHC карт. (Потому что для SDHC карт не получится передать невыровненный адрес).

Да, в HC это убрали, но и на обычных картах никто (или почти никто) такую запись не поддерживал.

Цитата(AHTOXA @ Mar 30 2015, 22:35) *
Что же до флага BUSY при мультиблоковой записи - не разу его не проверял, и не имел проблем. Возможно, с ним работает аппаратура SDIO контроллера.

BUSY, естественно, выставляется - иначе у карты не было бы возможности "притормозить" запись.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 31 2015, 09:25
Сообщение #20


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Если у кого есть информация, то любопытна и вторая вещь, о которой я писал. В SDHC BUSY может не вырабатываться после завершения мультисекторной записи. То есть карта накапливает непрерывные цепочки. Интересно, как давно и в каких типах такое стало происходить. И в связи с оптимизацией работы ПО с мультисекторной записью SD карт.

PS
Мой термин "невыравненная запись" отличался от документации SD-карт. Невыравненым считался адрес 512-байтного блока (не байта!) относительно грануляции NAND-памяти карты.

Сообщение отредактировал GetSmart - Mar 31 2015, 09:37


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ohmjke
сообщение Jul 19 2015, 18:02
Сообщение #21


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 27-01-10
Из: СПб
Пользователь №: 55 094



Пытаю SDIO на плате SK-STM32F217. Карту пока не подключал, хочу увидеть хоть какую-нибудь осмысленную активность на сигнальных линиях.
Осуществляю инициализацию и отправку команды, но вижу только мусор на линии CLK, на остальных ничего нет.
Может кто-нибудь проверить у себя мой вариант? Или подкинуть 100% рабочий код, без лишних функций.

Код
static SDIO_InitTypeDef s_sdio_param = {
                                         SDIO_ClockEdge_Rising,
                                         SDIO_ClockBypass_Enable,
                                         SDIO_ClockPowerSave_Disable,
                                         SDIO_BusWide_1b,
                                         SDIO_HardwareFlowControl_Disable,
                                         0
                                       };

void bsp_sd_init (void)
{
    SDIO_CmdInitTypeDef SDIO_CmdInitStruct;


    s_gpio_init();

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE);

    SDIO_SetPowerState(SDIO_PowerState_ON);
    while (SDIO_GetPowerState() != 0x03)
    {
        continue;
    }

    SDIO_Init(&s_sdio_param);

    SDIO_ClockCmd(ENABLE);

    SDIO_CmdInitStruct.SDIO_CmdIndex = 0xAA;
    SDIO_CmdInitStruct.SDIO_Argument = 0xCCCCCCCC;
    SDIO_CmdInitStruct.SDIO_Response = SDIO_Response_No;
    SDIO_CmdInitStruct.SDIO_CPSM     = ENABLE;
    SDIO_CmdInitStruct.SDIO_Wait     = SDIO_Wait_No;
    SDIO_SendCommand(&SDIO_CmdInitStruct);
}

static void s_gpio_init (void)
{
    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_AHB1PeriphClockCmd(RCC_CLK |
                           RCC_CMD |
                           RCC_D3  |
                           RCC_D2  |
                           RCC_D1  |
                           RCC_D0, ENABLE);

    GPIO_PinAFConfig(GPIO_CLK, PINSOURCE_CLK, GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIO_CMD, PINSOURCE_CMD, GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIO_D3,  PINSOURCE_D3,  GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIO_D2,  PINSOURCE_D2,  GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIO_D1,  PINSOURCE_D1,  GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIO_D0,  PINSOURCE_D0,  GPIO_AF_SDIO);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

    GPIO_InitStructure.GPIO_Pin = PIN_CMD;
    GPIO_Init(GPIO_CMD, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = PIN_D3;
    GPIO_Init(GPIO_D3,  &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = PIN_D2;
    GPIO_Init(GPIO_D2,  &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = PIN_D1;
    GPIO_Init(GPIO_D1,  &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = PIN_D0;
    GPIO_Init(GPIO_D0,  &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Pin  = PIN_CLK;
    GPIO_Init(GPIO_CLK, &GPIO_InitStructure);
}


Сообщение отредактировал ohmjke - Jul 19 2015, 18:03
Go to the top of the page
 
+Quote Post
ohmjke
сообщение Jul 24 2015, 16:46
Сообщение #22


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 27-01-10
Из: СПб
Пользователь №: 55 094



Ну что, никто не может помочь?
Go to the top of the page
 
+Quote Post
Мур
сообщение Jan 30 2018, 19:24
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Вопрос знатокам SDIO.(Завершаю мост на FPGA SDIO<-> N*UART)

Если по линии CMD кадр начинается с нулевого бита, то как обнаружить начало информационного кадра по DATA[3:0]? Я стал сомневаться, что для SD на входе CLK может отсутствовать частота (А значит именно её появление начинает отсчет информации).
Что наблюдали осциллографом? В Интернете противоречивая информация...
Go to the top of the page
 
+Quote Post
adnega
сообщение Jan 30 2018, 20:02
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Мур @ Jan 30 2018, 22:24) *
В Интернете противоречивая информация...

Судя по всему, начинается с "0".
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Мур
сообщение Jan 31 2018, 08:24
Сообщение #25


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Цитата(adnega @ Jan 30 2018, 23:02) *
Судя по всему, начинается с "0".

Это ценно. Огромное ВАМ спасибо!!!

...остается выяснить CRC вычисляется с учетом этого стартового нуля или ТОЛЬКО данные в учете?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 31 2018, 08:34
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Мур @ Jan 31 2018, 11:24) *
...остается выяснить CRC вычисляется с учетом этого стартового нуля или ТОЛЬКО данные в учете?

Только данные, по каждой линии отдельно.
Go to the top of the page
 
+Quote Post
adnega
сообщение Jan 31 2018, 09:23
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Мур @ Jan 31 2018, 11:24) *
Это ценно. Огромное ВАМ спасибо!!!

...остается выяснить CRC вычисляется с учетом этого стартового нуля или ТОЛЬКО данные в учете?

Рекомендую ознакомиться с SD Specifications Part 1 Physical Layer Simplified Specification Version 3.01:
Цитата
When the wide bus option is used, the data is transferred 4 bits at a time (refer to Figure 3-7). Start and
end bits, as well as the CRC bits, are transmitted for every one of the DAT lines. CRC bits are
calculated and checked for every DAT line individually. The CRC status response and Busy indication
will be sent by the card to the host on DAT0 only (DAT1-DAT3 during that period are don't care).

Более подробно про разные CRC описано в разделе 4.5 Cyclic Redundancy Code (CRC).
Go to the top of the page
 
+Quote Post
Мур
сообщение Jan 31 2018, 18:53
Сообщение #28


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Цитата(aaarrr @ Jan 31 2018, 11:34) *
Только данные, по каждой линии отдельно.

Странная фантазия... 4 вычислителя?... Трудно такую мысль представить у задумщиков SDIO
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 31 2018, 19:08
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Мур @ Jan 31 2018, 21:53) *
Странная фантазия... 4 вычислителя?... Трудно такую мысль представить у задумщиков SDIO

Странно было бы сделать иначе.
Go to the top of the page
 
+Quote Post
Мур
сообщение Jan 31 2018, 19:45
Сообщение #30


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Цитата(aaarrr @ Jan 31 2018, 22:08) *
Странно было бы сделать иначе.

Хм....
Проще гонять в сдвиговом регистре полином сразу по 4м линиям, чем 4мя по каждой из линий...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 31 2018, 20:11
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Мур @ Jan 31 2018, 22:45) *
Проще гонять в сдвиговом регистре полином сразу по 4м линиям, чем 4мя по каждой из линий...

Что может быть проще, чем иметь четыре сдвиговых регистра на выходе сериализатора? Минимум манипуляций с данными, минимум логики.
Go to the top of the page
 
+Quote Post
Мур
сообщение Feb 1 2018, 07:46
Сообщение #32


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Цитата(aaarrr @ Jan 31 2018, 23:11) *
Что может быть проще, чем иметь четыре сдвиговых регистра на выходе сериализатора? Минимум манипуляций с данными, минимум логики.

Смеётесь?....
В 4 раза больше логики в вашем случае! (16 триггеров против 64х).
Есть только одно объяснение этому "безобразию",- вариант применения одной линии данных вместо четырех. Тогда берется для этого один регистр из четырех.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 1 2018, 10:25
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Мур @ Feb 1 2018, 10:46) *
Смеётесь?....
В 4 раза больше логики в вашем случае! (16 триггеров против 64х).

16? Т.е. тактировать свой вычислитель с 4x частотой интерфейса - это не безобразие? А логику, которая
будет перекладывать полученное значение CRC в сериализатор, решили и не считать?
Go to the top of the page
 
+Quote Post
adnega
сообщение Feb 1 2018, 11:45
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Мур @ Feb 1 2018, 10:46) *
Смеётесь?....

А смысл обсуждать это? Есть стандарт - нужно ему следовать.
Если 4 вычислителя не охота делать принципиально, то можно с картой общаться в SPI-режиме, и вообще без какой-либо проверки.
Go to the top of the page
 
+Quote Post
mantech
сообщение Feb 1 2018, 11:55
Сообщение #35


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(adnega @ Feb 1 2018, 14:45) *
А смысл обсуждать это? Есть стандарт - нужно ему следовать.
Если 4 вычислителя не охота делать принципиально, то можно с картой общаться в SPI-режиме, и вообще без какой-либо проверки.


Если только скорость вообще не важна biggrin.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2018, 12:46
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(mantech @ Feb 1 2018, 13:55) *
Если только скорость вообще не важна biggrin.gif

А какой реальный выигрыш от использования SDIO вместо SPI не на коне в вакууме, а на типичном Cortex-M? Загруженном кроме гоняния байтов с SD ещё и другими задачами.
В Мб/сек или в %.
Есть-ли вообще смысл тратить гораздо больше ног МК, которые, как правило, всегда в дефиците?
Go to the top of the page
 
+Quote Post
adnega
сообщение Feb 1 2018, 13:03
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(jcxz @ Feb 1 2018, 15:46) *
А какой реальный выигрыш от использования SDIO вместо SPI не на коне в вакууме

Действительно, реальная карта очень медленная. Т.е. по быстрому интерфейсу ей прилетает команда,
спустя какое-то время карта по быстрому интерфейсу отвечает, а данные сектора выдаст гораааздо позже, но очень быстро.
Применение SDIO в связке с DMA позволяет сильно разгрузить МК, хотя я делал и на SPI+DMA+ISR с деревом из callback-функций.
С учетом того, что карта может приспокойно "задуматься" на полсекунды даже в режиме чтения, jcxz весьма справедлив.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2018, 13:15
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(adnega @ Feb 1 2018, 15:03) *
С учетом того, что карта может приспокойно "задуматься" на полсекунды даже в режиме чтения, jcxz весьма справедлив.

Я даже не об этом говорю, а о том что на практике я писал драйвер SD через SPI на Cortex-M 120МГц. И получал скорость потокового чтения с карты немного больше 1МБ/сек (естественно SPI+DMA).
Даже просто прокачка такого потока через средний Cortex-M сильно его нагрузит. Не говоря уже о том, что наверное МК должен как-то ещё и обрабатывать этот поток.
При более-менее содержательной обработке читаемых/записываемых данных, скорость обработки этих данных вряд-ли будет выше 1МБ/сек, а скорей всего - гораздо ниже.
Тогда такой скорости SPI вполне хватает.
И это при том, что я даже не оптимизировал свой драйвер - возможно получил бы гораздо бОльшую скорость (SPI-флешки у меня работают на SCLK до 40МГц).
Вобщем: при реальной работе с SD, а не мерянии попугаев, сама обработка данных будет больше тормозить, чем обмен с SD по SPI. Имха.
Так что польза от SDIO на типичных Cortex-M - сомнительна. Тоже - имхо.
Go to the top of the page
 
+Quote Post
_4afc_
сообщение Feb 1 2018, 13:32
Сообщение #39


Профессионал
*****

Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



Цитата(jcxz @ Feb 1 2018, 15:46) *
А какой реальный выигрыш от использования SDIO вместо SPI не на коне в вакууме, а на типичном Cortex-M? Загруженном кроме гоняния байтов с SD ещё и другими задачами.
В Мб/сек или в %.
Есть-ли вообще смысл тратить гораздо больше ног МК, которые, как правило, всегда в дефиците?


Есть проект на Cortex-M7 вида eMMC -> M7 -> HSUSB, без двойной буверизации, т.е. блок читается с флешки и отдаётся в USB.

При подключении по 4 проводам SDIO средня скорость чтения файла длиной 1Гб, в зависимости от частоты шины SDIO, составила:

24.43МГц - 6.50М/с;
25.00МГц - 7.18М/с;
50.00МГц - 10.56М/с.

Насколькоя я знаю скорость 50.00МГц предусмотрена стандартом только в режиме SDIO.

Цитата(adnega @ Feb 1 2018, 16:03) *
С учетом того, что карта может приспокойно "задуматься" на полсекунды даже в режиме чтения, jcxz весьма справедлив.


Моя карта имеет право задуматься на 250мс в режиме чтения.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2018, 13:47
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(_4afc_ @ Feb 1 2018, 15:32) *
Насколькоя я знаю скорость 50.00МГц предусмотрена стандартом только в режиме SDIO.

Просто передаёт с SD на USB? Это карт-ридер? rolleyes.gif
Конечно, если делать карт-ридер, то здесь имеет смысл. Я же писал про использование SD для нужд хранения и содержательной обработки данных самой программой МК.
Единственный вариант: это если данные медленно накапливать на SD при работе устройства, а потом быстро слить в комп не вынимая карты.

Цитата(_4afc_ @ Feb 1 2018, 15:32) *
Моя карта имеет право задуматься на 250мс в режиме чтения.

Да уж.... crying.gif
Go to the top of the page
 
+Quote Post
_4afc_
сообщение Feb 1 2018, 14:09
Сообщение #41


Профессионал
*****

Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



Цитата(jcxz @ Feb 1 2018, 16:47) *
Единственный вариант: это если данные медленно накапливать на SD при работе устройства, а потом быстро слить в комп не вынимая карты.

Да что-то подобное.

Цитата(jcxz @ Feb 1 2018, 16:47) *
Просто передаёт с SD на USB? Это карт-ридер? rolleyes.gif

В режиме чтения накопленной или обработанной информации - что-то типа карт-ридера. И естественно, чем быстрее считается - тем удобнее.

Цитата(jcxz @ Feb 1 2018, 16:47) *
Конечно, если делать карт-ридер, то здесь имеет смысл. Я же писал про использование SD для нужд хранения и содержательной обработки данных самой программой МК.


Для нужд записи - тоже имеет смысл при ограничении по потреблению и пульсациям по питанию.

Вот ток потребления в режиме SPI:
Прикрепленное изображение


А вот в режиме SDIO:
Прикрепленное изображение


Видно, что среднее потребление при записи - в режиме SDIO в 2.5 раза меньше, за счёт меньшего времени передачи данных.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2018, 14:17
Сообщение #42


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(_4afc_ @ Feb 1 2018, 16:09) *
Для нужд записи - тоже имеет смысл при ограничении по потреблению и пульсациям по питанию.
...
Видно, что среднее потребление при записи - в режиме SDIO в 2.5 раза меньше, за счёт меньшего времени передачи данных.

Зато судя по картинкам - пульсация тока в режиме SDIO в ~2 раза больше rolleyes.gif
Да и судя по длительностям осциллограмм - сравниваете SDIO работающий на высокой скорости и SPI работающий на медленной скорости - так сравнивать не корректно.
Вы сами писали, что скорость SDIO у вас максимум была 10МБ/сек. А SPI может работать с SCLK до 25МГц - т.е. около 3МБ/сек. Разница в длительности картинок должна быть соответственно 1/3 или 1/4 (судя по кол-ву линий IO).
Возможно, что если запустите SPI на макс. скорости, то получите сравнимые показатели тока потребления.
Go to the top of the page
 
+Quote Post
mantech
сообщение Feb 1 2018, 18:19
Сообщение #43


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(jcxz @ Feb 1 2018, 17:17) *
Вы сами писали, что скорость SDIO у вас максимум была 10МБ/сек. А SPI может работать с SCLK до 25МГц - т.е. около 3МБ/сек. Разница в длительности картинок должна быть соответственно 1/3 или 1/4 (судя по кол-ву линий IO).
Возможно, что если запустите SPI на макс. скорости, то получите сравнимые показатели тока потребления.


Только заметьте разницу - "корость SDIO у вас максимум была 10МБ/сек" и "А SPI может работать с SCLK до 25МГц - т.е. около 3МБ/сек" - только первое реально работает, а второе - только ваш прогноз, который не учитывает обработку команды в карте и накладные расходы, а именно больше полутора мегов в сек не получите по спи.
Другое дело - если задача скинуть файл пару кб раз в сек. то какой интерфейс - без разницы.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 1 2018, 18:53
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_4afc_ @ Feb 1 2018, 16:32) *
Насколькоя я знаю скорость 50.00МГц предусмотрена стандартом только в режиме SDIO.

Нет, режим High-Speed распространяется в том числе и на подключение через SPI.

P.S. SDIO и SD - это все-таки совершенно разные вещи.
Go to the top of the page
 
+Quote Post
Мур
сообщение Feb 2 2018, 07:49
Сообщение #45


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Цитата(aaarrr @ Jan 31 2018, 11:34) *
Только данные, по каждой линии отдельно.

Тут есть путаница,
.....хотя бы потому, что для вывода всего CRC16(CCITT) по ОДНОЙ линии требуется 16 тактов, хотя на эпюрах на это выделяется 4 такта. Неувязочка явная!

Ответ на этот вопрос резко бы упростился, если кто-нибудь дал пример РЕАЛЬНОЙ последовательности в четыре провода от начала до конца.
Go to the top of the page
 
+Quote Post
adnega
сообщение Feb 2 2018, 07:57
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Мур @ Feb 2 2018, 10:49) *
Ответ на этот вопрос резко бы упростился, если кто-нибудь дал пример РЕАЛЬНОЙ последовательности в четыре провода от начала до конца.

Дык, достаточно подключиться логическим анализатором к любому картридеру с картой.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 2 2018, 09:22
Сообщение #47


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Мур @ Feb 2 2018, 10:49) *
.....хотя бы потому, что для вывода всего CRC16(CCITT) по ОДНОЙ линии требуется 16 тактов, хотя на эпюрах на это выделяется 4 такта. Неувязочка явная!

На каких эпюрах?

Цитата из Physical Layer Simplified Specification Version 2.00:
Цитата
When the wide bus option is used, the data is transferred 4 bits at a time (refer to Figure 3-8). Start and
end bits, as well as the CRC bits, are transmitted for every one of the DAT lines. CRC bits are
calculated and checked for every DAT line individually.
Go to the top of the page
 
+Quote Post
Мур
сообщение Feb 2 2018, 13:57
Сообщение #48


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Цитата(aaarrr @ Feb 2 2018, 12:22) *
На каких эпюрах?


1111493779.gif вот это пример самодурства! Я увидел то, что хотел увидеть. ... Спасибо, дружище! Камень с плеч....

Делаю 16 тактов на CRC16(CCITT)!!!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 2 2018, 19:37
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Мур @ Feb 2 2018, 16:57) *
Я увидел то, что хотел увидеть. ...

Да, так оно и бывает иногда sm.gif
Go to the top of the page
 
+Quote Post
Мур
сообщение Feb 15 2018, 15:01
Сообщение #50


Знающий
****

Группа: Свой
Сообщений: 815
Регистрация: 7-06-06
Из: Харьков
Пользователь №: 17 847



Ёханый бабай!... Обращаю внимание http://www.sigmatone.com/utilities/crc_gener
Мужики! Вычисление CRC7 требует установку в исходное состояние регистров сдвигового регистра в "0000000", а не "1111111", как обычно.
Только так все работает
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 02:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.02123 секунд с 7
ELECTRONIX ©2004-2016