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

SDIO+Bypass STM32F4

Здравствуйте уважаемые форумчане!

Разбираюсь с SDIO режимом STM32F407VG. Встал вопрос скорости. Решил попробовать Bypass, т.е. брать чистые, неразделенные 48 MHz для тактирования карты. Команды вроде бы проходят, а вот взаимодействие (запись) с флеш-картой не завелось. Регулярно выбивается бит TXUNDERR, что говорит о незаполненности FIFO. Пользуюсь SPL, но даташит не игнорирую. Привожу код:

void Fast_Bus()// Перевод в режим быстрой шины после инициализации
{  
 send_command(7,RCA<<16,SDIO_CPSM_Enable,SDIO_Response_Short,SDIO_Wait_No,1);
 send_command(55,RCA<<16,SDIO_CPSM_Enable,SDIO_Response_Short,SDIO_Wait_No,1);
 send_command(6,0x00000002,SDIO_CPSM_Enable,SDIO_Response_Short,SDIO_Wait_No,1);

 SDIO_SetPowerState(SDIO_PowerState_OFF); 
 SDIO_InitTypeDef sdio;
 sdio.SDIO_BusWide=SDIO_BusWide_4b;
 sdio.SDIO_ClockBypass=SDIO_ClockBypass_Enable;
 sdio.SDIO_ClockDiv=0x00;
 sdio.SDIO_ClockEdge=SDIO_ClockEdge_Rising;
 sdio.SDIO_ClockPowerSave=SDIO_ClockPowerSave_Disable;
 sdio.SDIO_HardwareFlowControl=SDIO_HardwareFlowControl_Disable;
 SDIO_Init(&sdio);  
 SDIO_SetPowerState(SDIO_PowerState_ON);

 do
 {
SDIO->ICR=0xFFFFFFFF;
send_command(13,RCA<<16,SDIO_CPSM_Enable,SDIO_Response_Short,SDIO_Wait_No,0);
 }
 while(SDIO_GetResponse(SDIO_RESP1)!=0x00000900);  
}

void DPSM_Init()// Инициализация DPSM
{

  SDIO_DataInitTypeDef data;
  data.SDIO_DataBlockSize=SDIO_DataBlockSize_512b;
  data.SDIO_DataLength=512;
  data.SDIO_DataTimeOut=0x005B8D80; 
  data.SDIO_DPSM=SDIO_DPSM_Enable;
  data.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  data.SDIO_TransferMode=SDIO_TransferMode_Block;
  SDIO_DataConfig(&data);
}

void SD_Write(uint8_t const sector_data[],uint32_t sector,uint16_t count)// Собственно запись
{

 uint32_t dtlength=0;

 GPIO_ToggleBits(GPIOD,GPIO_Pin_12);

 for(int i=0;i<128*count;i++)
 {
 data_tr[i]=0x0;
 }
 uint32_t counter=0;

 for(int i=0;i<128*count;i++)
 {
  data_tr[i]|=(sector_data[counter++]);
  data_tr[i]|=(sector_data[counter++]<<8);
  data_tr[i]|=(sector_data[counter++]<<16);
  data_tr[i]|=(sector_data[counter++]<<24);		
 } 

 send_command(25,sector,SDIO_CPSM_Enable,SDIO_Response_Short,SDIO_Wait_No,0);   
 DPSM_Init();
 counter=0;

 do
 {	 
  if((SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE)==SET)&&(dtlength<(512)))
  {	

	  SDIO_WriteData(data_tr[counter++]);
	  SDIO_WriteData(data_tr[counter++]);  
	  SDIO_WriteData(data_tr[counter++]);
	  SDIO_WriteData(data_tr[counter++]);
	  SDIO_WriteData(data_tr[counter++]);
	  SDIO_WriteData(data_tr[counter++]);
	  SDIO_WriteData(data_tr[counter++]);
	  SDIO_WriteData(data_tr[counter++]);
 	  dtlength+=32;					  
  }

 }
 while ((SDIO_GetFlagStatus(SDIO_FLAG_DATAEND)|SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT)|S
DIO_GetFlagStatus(SDIO_FLAG_TXUNDERR)|SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL))!=SET); //

 DPSM_DeInit();
 send_command(12,0x0,SDIO_CPSM_Enable,SDIO_Response_Short,SDIO_Wait_No,0);// Вот здесь флаг выставлен.
 if(SDIO_GetResponse(SDIO_RESP1)!=0x00000900)
 {
DPSM_DeInit();	
do
{
  SDIO->ICR=0xFFFFFFFF;
  send_command(13,RCA<<16,SDIO_CPSM_Enable,SDIO_Response_Short,SDIO_Wait_No,0);
}
while(SDIO_GetResponse(SDIO_RESP1)!=0x00000900);		
  SDIO->ICR=0xFFFFFFFF;
 }
 else
 {
DPSM_DeInit();  
SDIO->ICR=0xFFFFFFFF;
 }

}

 

Вот как-то так. Помогите чайнику разобраться, очень бы хотелось активировать этот режим, т.к. иначе работа без запаса по времени почти. FAT губит все быстродействие(( Заранее благодарю откликнувшихся.

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

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


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

Читайте STM32F40x and STM32F41x Errata sheet — "SDIO clock divider BYPASS mode may not work properly"

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


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

А по DMA не проще будет "кормить" карту данными?

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


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

Genadi Zawidowski,DMA не используется по указанию свыше, т.е. руководитель проекта настоятельно не рекомендует его использовать. Почему-вопрос, но видимо есть причины.

Сега, про Err Datasheet спасибо, просто не знал о его существовании, сейчас буду пробовать. О результатах отпишусь, может поможет кому.

Спасибо.

 

Сега сверился с ErrData.

In high speed communication mode, when SDIO_CK is equal to 48 MHz

(PLL48_output = 48 MHz), the BYPASS bit is equal to ‘1’ and the NEGEDGE bit is equal to

‘0’ (respectively bit 10 and bit 13 in the SDIO_CLKCR register), the hold timing at the I/O pin

is not aligned with the SD/MMC 2.0 specifications.

Биты выставлены именно так, т.е. BYPASS=1, NEGEDGE=0. Карта поддерживает 48 МГц, это UHS-I.

Может быть, проблема в том, что я не перевел командой CMD6 в некий высокоскоростной режим?

 

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

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


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

Genadi Zawidowski,DMA не используется по указанию свыше, т.е. руководитель проекта настоятельно не рекомендует его использовать. Почему-вопрос, но видимо есть причины.

:smile3009: жесть какая.... Видимо начальник сам пробовал и у него не получилось.... или слышал звон...

Чувствуется - Вы сами толком не понимаете что Вам надо и как это работает.

Вообще-то DMA, при правильно организованной системе, нужен для разгрузки CPU. А на увеличение скорости обмена он напрямую не влияет.

Хотя.... в STM32 с их дохлой периферией без FIFO может быть всякое.....

Тупое увеличение частоты может совсем не принести нужного эффекта. Сначала нужно найти узкое место - где именно тормозит? И как построена работа с картой? И решить для себя вопрос - а сколько нужно-то (скорости)?

Возможно тогда поможет просто переписывание lowlevel-функций обмена с картой, ниже файловой системы. А также кеширование дисковых операций на этом уровне.

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


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

в STM32 с их дохлой периферией без FIFO

Как это без FIFO? В SDIO есть FIFO, другой вопрос почему оно не заполняется корректно, а после первой же итерации (судя по содержимому регистров) выплевывает ошибку. Причем именно в bypass режиме, в 24 МГц вежиме все классно, без затыков. Функции чтения/записи оптимизированы по самое нехочу, что там можно еще убрать-пока что непонятно.

Вы сами толком не понимаете что Вам надо

Прекрасно понимаю, надо считать данные с АЦП, сложить их в циклический буфер, читай программное FIFO, и успевать их выплевывать в файл, чтобы буфер не переполнялся. Частота считывания 200 КГц. Понимаю как работает DMA, но думаю, что оно не принесет ожидаемого прироста. А учитывая, что с DMA никогда не работал+требование руководства высказанное еще в пору AVR (раньше Xmega 64 была), экспериментировать не очень хочется, тем более не все выжато из SDIO.

 

Понимаете, скорости обмена хватает. Но впритык. Поэтому хотелось бы иметь запасец, на случай долгого "отдыха" карты после записи итд, ну сами понимаете, всякое может быть, лучше выжать максимум. Поэтому и заморочился 48 МГц режимом.

 

Хотя согласен с вами, некоторые вещи не совсем понятны на аппаратном уровне. DMA и SDIO к ним не относятся.

Тут дело либо в непереведенной в "быстрый режим" карте (хотя почему команды проходят тогда?), либо в том, что опыты ставлю на дискавери, через проводки (укороченные, но все же...). Либо еще в чем-то мною неизведанном пока что.

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


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

Прекрасно понимаю

Ну так если понимаете, то тогда ещё раз - где именно тормоза? Что именно надо ускорить? Именно сам обмен с картой? (Вы вообще смотрели временные диаграммы обмена по шине?) Или всё-таки программную обработку на уровне FS (или каком другом)? Или ваша работа на пользовательском уровне по запихиванию данных в файлы? Или операции записи/стирания на карту? Или ещё где? Где оценочный расклад какая часть процесса сколько занимает (в %)?

Как правило, когда для ускорения хотят тупо поднять частоту, то толком не понимают как именно работает весь процесс, где возникают основные расходы времени и тормоза.

Просто даже 24МГц - это даже для SPI очень прилично (3МБ/сек), такой поток процессору уровня Cortex-M и всему ПО, которое работает с этим потоком (файловая система и т.п.) уже довльно сложно переварить. А тут у Вас SDIO! Там ещё в разы больше поток. всё это говорит о том, что львиная доля времени будет уходить не на обмен с картой, а на программную обработку. И просто поднятие частоты даст прирост скорости всего на пару процентов.

Т.е. - Вы роете совсем не в том направлении.

Да и вообще что-то непонятно - как именно поток данных с АЦП на 200кГц может перегрузить карту работающую на 24МГц? Или у Вас несколько каналов или Вы ещё какие-то данные пишете на карту вместе?

Ещё раз вопрос - какие всё-таки требования по скорости записи??? какова скорость потока записываемых данных?

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


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

Что именно надо ускорить?

 

На данный момент именно обмен с картой надо довести до максимально возможного. Именно НИЗКОУРОВНЕВЫЕ функции надо оптимизировать/ускорить по максимуму. Я сейчас откинул в сторону ФС, отлаживаю только низкий уровень, обмен с картой. И кстати, переполнения при записи в файл идут именно в процессе чтения/записи, поэтому это я и полирую до блеска.

Вы вообще смотрели временные диаграммы обмена по шине?

 

Если речь идет о диаграммах в документации-то да, неоднократно.

Вы роете совсем не в том направлении.

 

Вполне возможно, но на этом этапе моя задача отполировать SDIO, задействовать его по полной программе. Я понимаю, что библиотека FAT не оптимальна, но ведь SDIO должна быть доведена до конца, т.е. скорость обмена должна быть максимальна.

как именно поток данных с АЦП на 200кГц может перегрузить карту работающую на 24МГц

 

Вот это мне не понятно. В режиме SPI при 24 МГц все тоже на соплях пролазило. Где-то задержка-буфер переполнен. Хотя запись шла вообще без ФС, просто по секторам.

Или у Вас несколько каналов или Вы ещё какие-то данные пишете на карту вместе?

 

Нет, на карту пишется только файл, правда Вы я думаю понимаете, что запись через FAT это не запись по секторам, т.е. медленнее дело идет, записывается дополнительная информация.

Ещё раз вопрос - какие всё-таки требования по скорости записи?

 

Ну вот смотрите: одна выборка - 5 мкс. Буфер может содержать до 40 тыс выборок, то бишь переполняется за 200 мс. Частота именно выкидывания данных должна быть где-то 10-20 КГц. Чем больше, тем меньше вероятности попасть в переполнение. Понятно, что карта пишет быстрее, иначе бы даже на соплях ничего бы не проходило. Но учитывая прихлопы ФАТ, открытие файла, заполнение, закрытие, итд итп скорость обмена заметно падает. Именно обмена, а не записи. То есть программа не оптимизирована, я согласен, наверняка в библиотеке есть места, которые можно выбросить или оптимизировать. НО! Сейчас, именно сейчас, стоит задача выжать все из SDIO, чтобы больше к нему не возвращаться.

 

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

 

Именно данные пишутся с мегабитными скоростями. Сейчас. Но опрос скажем занятости карты, завершения записи-все это тоже требует времени. Т.е. все вкупе выполняется медленнее, чем хотелось бы.

 

Поймите правильно, сейчас я вижу, что скорость обмена с картой можно увеличить, в том числе и для команд. И это надо реализовать, а не упереться в то что "не работает, ну и фиг с ним, займусь оптимизацией FAT". Вот я почему так настырно хочу увеличить частоту. После этого я переползу в FAT и спокойно буду оптимизировать его, зная что из SD выжат максимум, все что возможно.

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


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

Я сейчас откинул в сторону ФС, отлаживаю только низкий уровень, обмен с картой. И кстати, переполнения при записи в файл идут именно в процессе чтения/записи, поэтому это я и полирую до блеска.

Ну это и правильно - вначале надо отладить процесс обмена с картой без ФС.

Если у Вас идут переполнения, да ещё при таком огромном буфере (на 200 мсек), то смотрите временные диаграммы работы карты. А именно - время выполнения операций записи/стирания. Возможно у Вас тормоза именно в моменты когда карта внутренне пишет данные или стирает перед ними. Возможно надо ей давать команды предварительного стирания блоков (я работал с SD давно - деталей не помню). Попробуйте разные карты. Посмотрите в CSD всё что касается размеров блоков стирания и времён.

Карта при такой внутренней записи/стирании долго не выдаёт сигнал готовности.

 

Если речь идет о диаграммах в документации-то да, неоднократно.

Речь не о диаграммах в доках, а о диаграммах на экране осциллографа или логического анализатора. Сигналов на шине SDIO.

 

Нет, на карту пишется только файл, правда Вы я думаю понимаете, что запись через FAT это не запись по секторам, т.е. медленнее дело идет, записывается дополнительная информация.

Блин! Опять 25!

Мы здесь не телепаты чтобы знать как Вы эти свои 200kS/s выборок АЦП на карту пишете!

Это у Вас там все исходники и если спрашиваете помощи, то непонятно почему и тогда толком не расскажете что именно делаете?

Какова разрядность данных с АЦП? Сколько каналов АЦП? Как пишете просто бинарные данные или в текстовый вид преобразуете или ещё какую инфу к ним добавляете?

Т.е. - какова требуемая скорость потока записи в байтах/сек??? Я уже не знаю как ещё понятнее спросить.....

 

Ну вот смотрите: одна выборка - 5 мкс. Буфер может содержать до 40 тыс выборок, то бишь переполняется за 200 мс.

Ну что-ж - размер буфера выбран вроде достаточным.

 

Но учитывая прихлопы ФАТ, открытие файла, заполнение, закрытие, итд итп скорость обмена заметно падает. Именно обмена, а не записи.

Стоп! А вы что при записи каждой порции данных потока данных в файл его открываете/закрываете? а зачем??

А так - операции с FAT ускоряются например кешированием содержимого карты в ОЗУ.

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


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

Т.е. - какова требуемая скорость потока записи в байтах/сек??? Я уже не знаю как ещё понятнее спросить.....

 

А я уже не знаю как ответить. Сейчас АЦП, считывание и прочая святотень откинуты. Идет работа только с SDIO, записью. Я просто беру и пишу всякую фигню на карту, без АЦП. И это надо сделать максимально быстро, а не как получится. Я понимаю, чего Вы от меня хотите. Но Вы похоже не понимаете, чего я хочу от Вас. Я хочу разобраться с 48 МГц режимом, а не оптимизировать запись с АЦП, это другая часть работы.

 

Мы здесь не телепаты чтобы знать как Вы эти свои 200kS/s выборок АЦП на карту пишете!

 

Это отдельная песня, упомянул АЦП только потому, что хотел чтобы общее видение устройства сложилось. Повторюсь, сейчас пишу мусор.

 

  while(1)
  {
      delay(1000); 
          SD_Write(temp,i++,1);      
      GPIO_ToggleBits(GPIOD,GPIO_Pin_14);
  }

 

Вот именно так сейчас выглядит main (опущены процедуры инициализации). Т.е. про АЦП забыли, нету его. Извиняюсь, если внес сумятицу упоминанием об АЦП.

 

Стоп! А вы что при записи каждой порции данных потока данных в файл его открываете/закрываете? а зачем??

 

Зачем, действительно. Я создаю и пишу файл, который содержит 2 минуты записи с АЦП. Потом закрываю. Потом создаю новый без отрыва от считывания данных с АЦП и так далее. Требования такие.

 

По поводу диаграмм. Смотрел на осцилле, неоднократно.

 

Вот еще что. Название темы у нас SDIO+Bypass, а не отладка быстродействия карты памяти. Давайте будем обсуждать режим bypass, который надо запустить. А не сторонние вещи, вроде его необходимости в отдельно взятой программе. Это первая и не последняя работа с картами памяти. Чем больше я исследую сейчас SDIO, тем меньше придется изучать его потом.

 

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

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


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

А я уже не знаю как ответить. Сейчас АЦП, считывание и прочая святотень откинуты. Идет работа только с SDIO, записью. Я просто беру и пишу всякую фигню на карту, без АЦП. И это надо сделать максимально быстро, а не как получится. Я понимаю, чего Вы от меня хотите. Но Вы похоже не понимаете, чего я хочу от Вас. Я хочу разобраться с 48 МГц режимом, а не оптимизировать запись с АЦП, это другая часть работы.

 

RM0090 Reference manual, Doc ID 018909 Rev 6, p.1005/1710:

 

SDIO_CK is the clock to the card: one bit is transferred on both command and data lines

with each clock cycle. The clock frequency can vary between 0 MHz and 20 MHz (for a

MultiMediaCard V3.31), between 0 and 48 MHz for a MultiMediaCard V4.0/4.2, or between

0 and 25 MHz (for an SD/SD I/O card).

 

Так что 25 МГц -- это максимум для работы с SD карточкой. Кроме того, без DMA передача данных в SDIO будет прерываться на время обработки прерываний, что вызовет TXUNDERR. То, что у вас есть буфер на 200 мс -- это хорошо, но мало. Внимательно почитайте раздел 4.13 Speed Class Specification в документе SD Specifications Part 1 Physical Layer Simplified Specification; максимальное допустимое время обновления FAT для карточек -- 750 мс. Так что буфера менее чем на 800 мс может не хватить.

 

При записи на карточку основное время уходит на ожидание готовности карточки. Сама передача занимает вряд ли более 10% времени (при записи по одному сектору). Так что увеличение частоты в 2 раза, если бы это можно было сделать, даст прирост не более 5%. Гораздо больший выигрыш даст правильное выравнивание данных в памяти (чтобы писать блоками по 4 или 8 кБ за раз) и на карточке и предварительная подготовка карточки.

 

И еще про заполнение FIFO SDIO. При частоте 48 МГц (допустим, модуль будет работать) данные в FIFO нужно добавлять в среднем каждые 28 тактов (у вас же 4 линии данных?, ядро работает на частоте 168 МГц?). Функция SDIO_WriteData -- это не макрос! Вызов, возврат, считывание слова из памяти, запись в FIFO -- это всё запросто может длиться более 28 тактов. Так что без DMA вообще никак.

 

Илья

Изменено пользователем 501-q

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


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

501-q, читал подобные строки, поэтому меня и обуяли сомнения вообще в реализуемости этого режима. Где-то в спецификации SDIO видел, что UHS может работать на 48 МГц, отсюда и все метания по поводу допкоманды.

Спасибо за подробный ответ это было то, что нужно. Кстати, как ни странно, на соплях и с танцами с клоком процессор успешно проходит через прерывания и один файл пишет успешно, без переполнений.

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


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

Есть еще один нюанс, который не все знают, я на эти грабли когда-то наступил, даже добавил в фирмварю проверку скорости записи/чтения карточек при разной длине блока.

Скорость записи на карту ОЧЕНЬ сильно зависит от размера блока записи, и от того, как, точнее ЧЕМ она отформатирована.

Если ее не дай бог форматнули штатными средствами Винды - все, тушите свет. Скорость падает в РАЗЫ (вплоть до десятка раз!).

Есть программа - SDFormatter (гугглом легко находится), надо ею.

Но самое интересное - после нее многие карточки работали даже быстрее чем в "заводском" виде (т.е новая неюзанная карточка с магазина).

И писать блоками хотя бы по 4-8К, а лучше по 16-32, тогда достигается максимальная скорость.

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


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

Запускал на 48МГц по DMA и без DMA на ST32F429, всё работает, скорость возрастала минимум в раз 1.5 раза. На постоянку пока не оставлял из-за ограничений в документации, т.к. проект пока тестовый. Основная проблема скорости это задержки между записью/чтением блоков и при использовании Fat эти задержки приходится ждать обычными while или попытаться сделать что нибудь полезное в это время. При чтении задержки меньше в 1,5-2 раза чем при записи. Например при чтении будут 500 мксек, а при записи 2000 мксек. Переодически возникают более длительные задержки, скорее всего при переходе между секторами карты порядка 5-30 мсек. Задержки зависят от размера блока, чем больше, тем больше задержка, но писать большими блоками выгоднее. Блоки больше 16-32кб в большинстве случаев выигрыша по скорости не дадут.

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


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

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

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

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

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

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

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

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

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

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