Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Как разогнать DCMI на STM32?

Вс авг 04, 2019 08:24:23

Всем привет! Имеется несколько микроконтроллеров (f407, f429, f469), к ним я хочу приделать внешний АЦП AD9283BRSZ-100 (8 бит, 10MSPS).
Но вот незадача, больше 54 мегасемплов в секунду этот интерфейс брать не хочет. Если подавать клоки 60 МГц, то интерфейс перестает считывать байты, хотя фронты более, чем четкие.
Гнал проц с 180 до 220, толку ноль.

Можно ли как-то поднять частоту семплирования для интерфейса DCMI?

Re: Как разогнать DCMI на STM32?

Вс авг 04, 2019 08:39:37

Для 8-ми бит DCMI может забирать данные за 2 такта если клок генерит тот же мк. Ничего для этого специально делать не нужно.

Re: Как разогнать DCMI на STM32?

Вс авг 04, 2019 14:06:04

Проблема не в DCMI а в DMA.
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.

Re: Как разогнать DCMI на STM32?

Вс авг 04, 2019 14:28:30

Проблема не в DCMI а в DMA.
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.

DMA можно настроить так, что для 8 бит будет одна передача каждые 8 тактов. У меня DMCI работало с DMA на 120 MHz, тут еще есть тема про осцилл там тоже работает на 100 или 120 MHz... Если у ТС ничего не меняется с увеличением частоты, то скорее из-за разводки, если там вообще все на проводках не болтается...

ps. Забыл добавить, для таких скоростей без __WFI() равномерной работы вряд ли получится добиться.

Re: Как разогнать DCMI на STM32?

Вс авг 04, 2019 21:02:22

Проблема не в DCMI а в DMA.
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.

А вот тут есть загвоздка! Dma пришлось настроить, чтобы он перемещал по 32 бита, иначе работать отказывается. Может, тут косяк?
Dcmi настроен на 8 ног(бит) и внешние клоки.
При частоте проца 200 МГц и 50 МГЦ клоков для dcmi снимает норм, а при 60 уже фиг - в буфер ничего не складывается и счётчик dma застывает на месте.

Добавлено after 11 minutes 58 seconds:
Для 8-ми бит DCMI может забирать данные за 2 такта если клок генерит тот же мк. Ничего для этого специально делать не нужно.

Я пробовал генерить клоки ногой от интерфейса quadspi через пересылку одного и того же байта через dma, но проц отказывался складывать в буфер данные даже при частоте клоков 50 МГц.
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?

Re: Как разогнать DCMI на STM32?

Вс авг 04, 2019 21:21:34

Я пробовал генерить клоки ногой от интерфейса quadspi через пересылку одного и того же байта через dma, но проц отказывался складывать в буфер данные даже при частоте клоков 50 МГц.
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?

Как вообще до такого можно было додуматься? :) Есть таймеры, есть MCO... Конечно второй DMA может мешать, даже при том, что у DCMI регистр данных 32-х битный и туда 4 раза пакуются 8 бит перед передачей. А может и не мешать, я без понятия, но никаких quadspi во время тестирования быть не должно...

Re: Как разогнать DCMI на STM32?

Вс авг 04, 2019 22:32:22

Я пробовал генерить клоки ногой от интерфейса quadspi через пересылку одного и того же байта через dma, но проц отказывался складывать в буфер данные даже при частоте клоков 50 МГц.
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?

Как вообще до такого можно было додуматься? :) Есть таймеры, есть MCO... Конечно второй DMA может мешать, даже при том, что у DCMI регистр данных 32-х битный и туда 4 раза пакуются 8 бит перед передачей. А может и не мешать, я без понятия, но никаких quadspi во время тестирования быть не должно...

:))) Согласен! Если ничего не помогает - читай инструкцию. И всё же, я не нашёл максимальную частоту, которую можно сгенерировать ногой MCO...

Re: Как разогнать DCMI на STM32?

Вс авг 04, 2019 22:52:09

И всё же, я не нашёл максимальную частоту, которую можно сгенерировать ногой MCO...

F/2/3/4/5.

Re: Как разогнать DCMI на STM32?

Пн авг 05, 2019 11:19:50

DMA и ядро ARM постоянно борются арбитражем за право использовать ту или иную шину данных. При этом ARM ядру доступно ожидание в 2 такта и более высокий приоритет, а вот для DMA ожидание уже 4 такта. То-есть в условии свободной шины - ждать придётся 4 такта. После первой пересылки данных - DMA может лить поток без ограничений, но у него просто кончаются данные FIFO.
Условие при котором будет максимальная скорость - полностью загруженное FIFO, отсутствие конкурентов, выгрузка 32б за удар - чтобы снизить нагрузку с шины.

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

Кстати F7 в состоянии принимать поток с qspi в DDR режиме с двух чипов на скорости 1/2 от системной - это 200 Мбайт при тактовой в 200МГц. При этом DMA будет пересылать по 32 байт за удар (8 циклов), и выигрывать арбитраж в следующие 4 цикла. FIFO qspi в два раза больше чем FIFO DMA - это позволяет прокачивать шину максимальным количеством данных.
Теоретическая планка скорости данных шины 800 Мбайт, но такой поток чисто физически невозможно сформировать.
Последний раз редактировалось AVI-crak Пн авг 05, 2019 11:40:38, всего редактировалось 1 раз.

Re: Как разогнать DCMI на STM32?

Пн авг 05, 2019 11:26:08

Настроил ногу MCO1 на такт 50 МГц, работает. На 66.66 МГц - буфер не заполняется.
Вот так инициализирую DCMI и RCC:
Код:
   HAL_RCC_MCOConfig(RCC_MCO1,RCC_MCO1SOURCE_PLLCLK,RCC_MCODIV_3);//Config clocks for DCMI ON PA8
   
   /* DMA parameter configuration*/
   hdcmi_dma.Instance = DMA2_Stream1;
   hdcmi_dma.Init.Channel = DMA_CHANNEL_1;
   hdcmi_dma.Init.Direction = DMA_PERIPH_TO_MEMORY;
   hdcmi_dma.Init.PeriphInc = DMA_PINC_DISABLE;
   hdcmi_dma.Init.MemInc = DMA_MINC_ENABLE;
   hdcmi_dma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
   hdcmi_dma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdcmi_dma.Init.Mode = DMA_NORMAL;
   hdcmi_dma.Init.Priority = DMA_PRIORITY_VERY_HIGH;
   hdcmi_dma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   HAL_DMA_Init(&hdcmi_dma);

   // DCMI parameter configuration//
   hdcmi.Instance = DCMI;
   hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
   hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
   hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW;
   hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
   hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
   hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
   hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
   hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL;
   HAL_DCMI_Init(&hdcmi);


Вот так запускаю считывание:
Код:
void DCMI_StartCapture(uint32_t buff_addr, uint32_t count){
   DMA2->LIFCR = DMA_LIFCR_CFEIF1 | DMA_LIFCR_CDMEIF1 | DMA_LIFCR_CTEIF1 | DMA_LIFCR_CHTIF1 | DMA_LIFCR_CTCIF1;// Clear all interrupt flags on DMA2->Stream1
   hdcmi_dma.Instance->CR &= ~DMA_SxCR_EN;//Disable DCMI_DMA

   hdcmi.Instance->CR &= ~(DCMI_CR_ENABLE | DCMI_CR_CAPTURE);//DCMI_CR_ENABLE//Disable DCMI
   
   hdcmi_dma.Instance->M0AR = buff_addr;
   hdcmi_dma.Instance->PAR = (uint32_t)(&hdcmi.Instance->DR);
   hdcmi_dma.Instance->NDTR = count;
   
   hdcmi.Instance->CR |= DCMI_CR_ENABLE | DCMI_CR_CAPTURE;//DCMI_CR_ENABLE//Enable DCMI
   hdcmi_dma.Instance->CR |= DMA_SxCR_EN;//Enable DCMI_DMA
   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);//Нога для дрыгания HSYNC и VSYNC
}

Подскажите, где косячу?

Re: Как разогнать DCMI на STM32?

Пн авг 05, 2019 12:11:30

Нашел код где я игрался с DCMI:
Код:
   PB7 dcmi_vsynk(PinMode::AF_PullUp, 13);
   PA4 dcmi_hsynk(PinMode::AF_PullUp, 13);
   PA7 dcmi_ctrv(PinMode::PushPull);
   PA6 dcmi_pixclk(PinMode::AF_PullDown, 13);
   dcmi_ctrv.set();

   DCMI->CR = 0;   // 8 bits

   Dma2Stream7<1> stream;
   stream.initPeriphToMem(&DCMI->DR, DmaSrc::_32b, buf, DmaDst::_32b_Inc, 10000, DmaPrio::VeryHigh);

   DCMI->CR = DCMI_CR_CAPTURE | DCMI_CR_ENABLE;
   stream.enable();
   dcmi_ctrv.clear();
   __NOP();
   __NOP();
   dcmi_ctrv.set();

Старт по импульсу, ctrv шел на vsynk или hsynk, точно не помню :)

Re: Как разогнать DCMI на STM32?

Вт авг 06, 2019 10:17:56

Нашел код где я игрался с DCMI:
Код:
   PB7 dcmi_vsynk(PinMode::AF_PullUp, 13);
   PA4 dcmi_hsynk(PinMode::AF_PullUp, 13);
   PA7 dcmi_ctrv(PinMode::PushPull);
   PA6 dcmi_pixclk(PinMode::AF_PullDown, 13);
   dcmi_ctrv.set();

   DCMI->CR = 0;   // 8 bits

   Dma2Stream7<1> stream;
   stream.initPeriphToMem(&DCMI->DR, DmaSrc::_32b, buf, DmaDst::_32b_Inc, 10000, DmaPrio::VeryHigh);

   DCMI->CR = DCMI_CR_CAPTURE | DCMI_CR_ENABLE;
   stream.enable();
   dcmi_ctrv.clear();
   __NOP();
   __NOP();
   dcmi_ctrv.set();

Старт по импульсу, ctrv шел на vsynk или hsynk, точно не помню :)


В общем-то всё так же. Неужели, __WFI() помогает работать dcmi в 2 раза быстрее? Или, может, дело во фронтах ноги mco1?

Re: Как разогнать DCMI на STM32?

Вт авг 06, 2019 10:26:13

В общем-то всё так же. Неужели, __WFI() помогает работать dcmi в 2 раза быстрее? Или, может, дело во фронтах ноги mco1?

Я подавал с шима F/2, если скорость для пина на максимуме и соединено не километровыми проводами, или короткими, но воткнутыми в макетку, то проблем быть не должно. __WFI() дает стабильно 2 такта, без него может быть в среднем 2.1 или 2.01, но никак не 4.

Re: Как разогнать DCMI на STM32?

Вт авг 06, 2019 10:47:43

В общем-то всё так же. Неужели, __WFI() помогает работать dcmi в 2 раза быстрее? Или, может, дело во фронтах ноги mco1?

Я подавал с шима F/2, если скорость для пина на максимуме и соединено не километровыми проводами, или короткими, но воткнутыми в макетку, то проблем быть не должно. __WFI() дает стабильно 2 такта, без него может быть в среднем 2.1 или 2.01, но никак не 4.


А пин MCO у Вас всегда генерил клоки? Даже когда данные с DCMI не снимались?
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.

Re: Как разогнать DCMI на STM32?

Вт авг 06, 2019 10:57:48

А пин MCO у Вас всегда генерил клоки? Даже когда данные с DCMI не снимались?
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.

Не MCO, было подключено к PWM, отключалось или нет не помню, но тестил я на проекте осцилла/ЛА, так что вывод был на экран и можно было сравнить по скорости с захватом с порта, т.е. 2 такта там точно было. Хотя в итоге я от DCMI отказался, потому что было нужно не только чтение, но и запись.

Re: Как разогнать DCMI на STM32?

Вт авг 06, 2019 11:09:05

А пин MCO у Вас всегда генерил клоки? Даже когда данные с DCMI не снимались?
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.

Не MCO, было подключено к PWM, отключалось или нет не помню, но тестил я на проекте осцилла/ЛА, так что вывод был на экран и можно было сравнить по скорости с захватом с порта, т.е. 2 такта там точно было. Хотя в итоге я от DCMI отказался, потому что было нужно не только чтение, но и запись.


А что за микросхему Вы использовали для АЦПирования, если не секрет?

Re: Как разогнать DCMI на STM32?

Вт авг 06, 2019 11:12:25

А что за микросхему Вы использовали для АЦПирования, если не секрет?

ADC встроенный использовался, на F4 в разгоне для одного канала выходило 12MSPS для 12 бит, а с порта данные для ЛА читались.
Ответить