Как разогнать DCMI на STM32?
Как разогнать DCMI на STM32?
Всем привет! Имеется несколько микроконтроллеров (f407, f429, f469), к ним я хочу приделать внешний АЦП AD9283BRSZ-100 (8 бит, 10MSPS).
Но вот незадача, больше 54 мегасемплов в секунду этот интерфейс брать не хочет. Если подавать клоки 60 МГц, то интерфейс перестает считывать байты, хотя фронты более, чем четкие.
Гнал проц с 180 до 220, толку ноль.
Можно ли как-то поднять частоту семплирования для интерфейса DCMI?
Но вот незадача, больше 54 мегасемплов в секунду этот интерфейс брать не хочет. Если подавать клоки 60 МГц, то интерфейс перестает считывать байты, хотя фронты более, чем четкие.
Гнал проц с 180 до 220, толку ноль.
Можно ли как-то поднять частоту семплирования для интерфейса DCMI?
Купил лазерный принтер... Теперь осталось спаять машину времени и прислать себе принтер пораньше =D
Re: Как разогнать DCMI на STM32?
Для 8-ми бит DCMI может забирать данные за 2 такта если клок генерит тот же мк. Ничего для этого специально делать не нужно.
- AVI-crak
- Прорезались зубы
- Сообщения: 202
- Зарегистрирован: Сб янв 09, 2016 15:51:17
- Контактная информация:
Re: Как разогнать DCMI на STM32?
Проблема не в DCMI а в DMA.
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.
Re: Как разогнать DCMI на STM32?
[uquote="AVI-crak",url="/forum/viewtopic.php?p=3676826#p3676826"]Проблема не в DCMI а в DMA.
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.[/uquote]
DMA можно настроить так, что для 8 бит будет одна передача каждые 8 тактов. У меня DMCI работало с DMA на 120 MHz, тут еще есть тема про осцилл там тоже работает на 100 или 120 MHz... Если у ТС ничего не меняется с увеличением частоты, то скорее из-за разводки, если там вообще все на проводках не болтается...
ps. Забыл добавить, для таких скоростей без __WFI() равномерной работы вряд ли получится добиться.
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.[/uquote]
DMA можно настроить так, что для 8 бит будет одна передача каждые 8 тактов. У меня DMCI работало с DMA на 120 MHz, тут еще есть тема про осцилл там тоже работает на 100 или 120 MHz... Если у ТС ничего не меняется с увеличением частоты, то скорее из-за разводки, если там вообще все на проводках не болтается...
ps. Забыл добавить, для таких скоростей без __WFI() равномерной работы вряд ли получится добиться.
Re: Как разогнать DCMI на STM32?
[uquote="AVI-crak",url="/forum/viewtopic.php?p=3676826#p3676826"]Проблема не в DCMI а в DMA.
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.[/uquote]
А вот тут есть загвоздка! Dma пришлось настроить, чтобы он перемещал по 32 бита, иначе работать отказывается. Может, тут косяк?
Dcmi настроен на 8 ног(бит) и внешние клоки.
При частоте проца 200 МГц и 50 МГЦ клоков для dcmi снимает норм, а при 60 уже фиг - в буфер ничего не складывается и счётчик dma застывает на месте.
Добавлено after 11 minutes 58 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3676621#p3676621"]Для 8-ми бит DCMI может забирать данные за 2 такта если клок генерит тот же мк. Ничего для этого специально делать не нужно.[/uquote]
Я пробовал генерить клоки ногой от интерфейса quadspi через пересылку одного и того же байта через dma, но проц отказывался складывать в буфер данные даже при частоте клоков 50 МГц.
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?
Для максимальной скорости DMA должен принимать 32бита, а отдавать 64.[/uquote]
А вот тут есть загвоздка! Dma пришлось настроить, чтобы он перемещал по 32 бита, иначе работать отказывается. Может, тут косяк?
Dcmi настроен на 8 ног(бит) и внешние клоки.
При частоте проца 200 МГц и 50 МГЦ клоков для dcmi снимает норм, а при 60 уже фиг - в буфер ничего не складывается и счётчик dma застывает на месте.
Добавлено after 11 minutes 58 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3676621#p3676621"]Для 8-ми бит DCMI может забирать данные за 2 такта если клок генерит тот же мк. Ничего для этого специально делать не нужно.[/uquote]
Я пробовал генерить клоки ногой от интерфейса quadspi через пересылку одного и того же байта через dma, но проц отказывался складывать в буфер данные даже при частоте клоков 50 МГц.
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?
Купил лазерный принтер... Теперь осталось спаять машину времени и прислать себе принтер пораньше =D
Re: Как разогнать DCMI на STM32?
[uquote="allplayer",url="/forum/viewtopic.php?p=3677070#p3677070"]Я пробовал генерить клоки ногой от интерфейса quadspi через пересылку одного и того же байта через dma, но проц отказывался складывать в буфер данные даже при частоте клоков 50 МГц.
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?[/uquote]
Как вообще до такого можно было додуматься?
Есть таймеры, есть MCO... Конечно второй DMA может мешать, даже при том, что у DCMI регистр данных 32-х битный и туда 4 раза пакуются 8 бит перед передачей. А может и не мешать, я без понятия, но никаких quadspi во время тестирования быть не должно...
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?[/uquote]
Как вообще до такого можно было додуматься?
Re: Как разогнать DCMI на STM32?
[uquote="Reflector",url="/forum/viewtopic.php?p=3677079#p3677079"][uquote="allplayer",url="/forum/viewtopic.php?p=3677070#p3677070"]Я пробовал генерить клоки ногой от интерфейса quadspi через пересылку одного и того же байта через dma, но проц отказывался складывать в буфер данные даже при частоте клоков 50 МГц.
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?[/uquote]
Как вообще до такого можно было додуматься?
Есть таймеры, есть MCO... Конечно второй DMA может мешать, даже при том, что у DCMI регистр данных 32-х битный и туда 4 раза пакуются 8 бит перед передачей. А может и не мешать, я без понятия, но никаких quadspi во время тестирования быть не должно...[/uquote]
Согласен! Если ничего не помогает - читай инструкцию. И всё же, я не нашёл максимальную частоту, которую можно сгенерировать ногой MCO...
Может, это из-за того, что используется dma2 для quadspi и dcmi одновременно?[/uquote]
Как вообще до такого можно было додуматься?
Купил лазерный принтер... Теперь осталось спаять машину времени и прислать себе принтер пораньше =D
Re: Как разогнать DCMI на STM32?
[uquote="allplayer",url="/forum/viewtopic.php?p=3677112#p3677112"]И всё же, я не нашёл максимальную частоту, которую можно сгенерировать ногой MCO...[/uquote]
F/2/3/4/5.
F/2/3/4/5.
- AVI-crak
- Прорезались зубы
- Сообщения: 202
- Зарегистрирован: Сб янв 09, 2016 15:51:17
- Контактная информация:
Re: Как разогнать DCMI на STM32?
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 Мбайт, но такой поток чисто физически невозможно сформировать.
Условие при котором будет максимальная скорость - полностью загруженное 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?
Настроил ногу MCO1 на такт 50 МГц, работает. На 66.66 МГц - буфер не заполняется.
Вот так инициализирую DCMI и RCC:
Вот так запускаю считывание:
Подскажите, где косячу?
Вот так инициализирую 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
}
Купил лазерный принтер... Теперь осталось спаять машину времени и прислать себе принтер пораньше =D
Re: Как разогнать DCMI на STM32?
Нашел код где я игрался с DCMI:
Старт по импульсу, ctrv шел на vsynk или hsynk, точно не помню 
Код: Выделить всё
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();Re: Как разогнать DCMI на STM32?
[uquote="Reflector",url="/forum/viewtopic.php?p=3677322#p3677322"]Нашел код где я игрался с DCMI:
Старт по импульсу, ctrv шел на vsynk или hsynk, точно не помню
[/uquote]
В общем-то всё так же. Неужели, __WFI() помогает работать dcmi в 2 раза быстрее? Или, может, дело во фронтах ноги mco1?
Код: Выделить всё
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();В общем-то всё так же. Неужели, __WFI() помогает работать dcmi в 2 раза быстрее? Или, может, дело во фронтах ноги mco1?
Купил лазерный принтер... Теперь осталось спаять машину времени и прислать себе принтер пораньше =D
Re: Как разогнать DCMI на STM32?
[uquote="allplayer",url="/forum/viewtopic.php?p=3677763#p3677763"]В общем-то всё так же. Неужели, __WFI() помогает работать dcmi в 2 раза быстрее? Или, может, дело во фронтах ноги mco1?[/uquote]
Я подавал с шима F/2, если скорость для пина на максимуме и соединено не километровыми проводами, или короткими, но воткнутыми в макетку, то проблем быть не должно. __WFI() дает стабильно 2 такта, без него может быть в среднем 2.1 или 2.01, но никак не 4.
Я подавал с шима F/2, если скорость для пина на максимуме и соединено не километровыми проводами, или короткими, но воткнутыми в макетку, то проблем быть не должно. __WFI() дает стабильно 2 такта, без него может быть в среднем 2.1 или 2.01, но никак не 4.
Re: Как разогнать DCMI на STM32?
[uquote="Reflector",url="/forum/viewtopic.php?p=3677766#p3677766"][uquote="allplayer",url="/forum/viewtopic.php?p=3677763#p3677763"]В общем-то всё так же. Неужели, __WFI() помогает работать dcmi в 2 раза быстрее? Или, может, дело во фронтах ноги mco1?[/uquote]
Я подавал с шима F/2, если скорость для пина на максимуме и соединено не километровыми проводами, или короткими, но воткнутыми в макетку, то проблем быть не должно. __WFI() дает стабильно 2 такта, без него может быть в среднем 2.1 или 2.01, но никак не 4.[/uquote]
А пин MCO у Вас всегда генерил клоки? Даже когда данные с DCMI не снимались?
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.
Я подавал с шима F/2, если скорость для пина на максимуме и соединено не километровыми проводами, или короткими, но воткнутыми в макетку, то проблем быть не должно. __WFI() дает стабильно 2 такта, без него может быть в среднем 2.1 или 2.01, но никак не 4.[/uquote]
А пин MCO у Вас всегда генерил клоки? Даже когда данные с DCMI не снимались?
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.
Купил лазерный принтер... Теперь осталось спаять машину времени и прислать себе принтер пораньше =D
Re: Как разогнать DCMI на STM32?
[uquote="allplayer",url="/forum/viewtopic.php?p=3677773#p3677773"]А пин MCO у Вас всегда генерил клоки? Даже когда данные с DCMI не снимались?
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.[/uquote]
Не MCO, было подключено к PWM, отключалось или нет не помню, но тестил я на проекте осцилла/ЛА, так что вывод был на экран и можно было сравнить по скорости с захватом с порта, т.е. 2 такта там точно было. Хотя в итоге я от DCMI отказался, потому что было нужно не только чтение, но и запись.
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.[/uquote]
Не MCO, было подключено к PWM, отключалось или нет не помню, но тестил я на проекте осцилла/ЛА, так что вывод был на экран и можно было сравнить по скорости с захватом с порта, т.е. 2 такта там точно было. Хотя в итоге я от DCMI отказался, потому что было нужно не только чтение, но и запись.
Re: Как разогнать DCMI на STM32?
[uquote="Reflector",url="/forum/viewtopic.php?p=3677780#p3677780"][uquote="allplayer",url="/forum/viewtopic.php?p=3677773#p3677773"]А пин MCO у Вас всегда генерил клоки? Даже когда данные с DCMI не снимались?
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.[/uquote]
Не MCO, было подключено к PWM, отключалось или нет не помню, но тестил я на проекте осцилла/ЛА, так что вывод был на экран и можно было сравнить по скорости с захватом с порта, т.е. 2 такта там точно было. Хотя в итоге я от DCMI отказался, потому что было нужно не только чтение, но и запись.[/uquote]
А что за микросхему Вы использовали для АЦПирования, если не секрет?
А то у меня программа в HardFault_Handler сваливается при попытке отключить DCMI после передачи всех байт.[/uquote]
Не MCO, было подключено к PWM, отключалось или нет не помню, но тестил я на проекте осцилла/ЛА, так что вывод был на экран и можно было сравнить по скорости с захватом с порта, т.е. 2 такта там точно было. Хотя в итоге я от DCMI отказался, потому что было нужно не только чтение, но и запись.[/uquote]
А что за микросхему Вы использовали для АЦПирования, если не секрет?
Купил лазерный принтер... Теперь осталось спаять машину времени и прислать себе принтер пораньше =D
Re: Как разогнать DCMI на STM32?
[uquote="allplayer",url="/forum/viewtopic.php?p=3677784#p3677784"]А что за микросхему Вы использовали для АЦПирования, если не секрет?[/uquote]
ADC встроенный использовался, на F4 в разгоне для одного канала выходило 12MSPS для 12 бит, а с порта данные для ЛА читались.
ADC встроенный использовался, на F4 в разгоне для одного канала выходило 12MSPS для 12 бит, а с порта данные для ЛА читались.