STM32H7 DCMI с BT.656
В настоящее время я делаю систему с использованием цифровой камеры, разрешение моей камеры 384x288 4:2:2 YCbCr. Моя камера работает на BT.656 со встроенной синхронизацией (без аппаратной синхронизации). Я настроил STM32 DCMI со встроенной синхронизацией, и это не сработало. Затем я начал его отлаживать и обнаружил странную проблему с DCMI STM32:
STM32 DCMI, встроенный для BT.656, инвертирован.
Документ STM32 DCMI (из AN5020 ST):
Протокол BT.656 (отсюда):
У меня 2 вопроса:
- У кого-нибудь получилось заставить работать BT.656 на STM32H7 или любом STF32FXX?
- Разрешение BT.656 для PAL составляет 720x576, а у моей камеры - 384x288. Какой формат у камеры? Или: Как я могу понять, сколько строк используется?
1 ответ
У меня аналогичная проблема с использованием STM32MP157 — к сожалению, дискретная синхронизация для DCMI недоступна на нашей плате ЦП, поэтому мне пришлось заставить ее работать, несмотря ни на что. Хорошей новостью является то, что он работает и работает хорошо, но есть некоторые вещи, на которые следует обратить внимание.
Справочное руководство немного кратко описывает, что нужно сделать, но дает пару советов.
DCMI_ESUR=0xFFFFFFFF;DCMI_ESCR=0xB69D80AB;
Если вас устраивает захват только одного поля, установите ESCR на нечетные или четные коды полей по вашему желанию. Если вам нужны оба поля, установите DCMI_ESUR=0xB0B0B0B0, чтобы бит поля игнорировался.
Включите прерывания DCMI для HSync и VSync — остальное можно игнорировать. В вашем прерывании подсчитайте состояния MIR 0x18 и 0x10, прежде чем очистить флаги. Сумма обоих дает вам количество строк активного видео плюс период вертикальной синхронизации для общего количества строк для захваченного поля. Если вы разрешаете как нечетное, так и четное поле, счетчик сообщит вам, захватили ли вы только что нечетное или четное поле. Во время VSync в выбранное вами время настройте DMA для начала нового захвата (1440 байт на строку, если PAL или NTSC). DCMI предоставит вам только активные пиксели (а не те, которые находятся в периоде HSync). Убедитесь, что вы используете DMA с включенным FIFO в словном (32-битном) режиме. Это всего лишь 4 слова, но оно вам нужно — пиксели появляются быстро. В моем случае я настраиваю DMA в циклическом режиме с двойным буфером, записывая всего две строки во внутреннюю SRAM, что происходит быстро. В каждом конце передачи (одна строка) я использую MDMA для копирования последней строки, полученной из SRAM в DRAM, в окончательный буфер кадра - здесь вы можете хорошо использовать больший внутренний FIFO MDMA. Вам необходимо избегать переполнения DCMI, а также обращать внимание на условия гонки между прерываниями DCMI и прерываниями DMA. Я делаю это в M4, чтобы избежать задержки прерываний в Linux. Если вы захватываете только нечетные или четные поля - увеличьте адрес строки буфера кадра на свой шаг - если он нечетный и четный, увеличьте вдвое шаг, позаботившись об установке правильного адреса начальной строки после VSYNC в зависимости от количества строк, что дает вам нечетное или четное поле. Обрезка не работает во встроенном режиме синхронизации, но ее легко добиться с помощью MDMA и счетчика строк. Наконец, пользователи STM32MP157, возможно, заметили, что ST забыл включить некоторые средства аппаратного преобразования из YCbYCr в RGB (DMA2D здесь не существует). В более поздних версиях чипа LDTC может это делать, но это не очень полезно, поскольку, вероятно, вам нужно масштабировать перед отображением, а вы действительно не хотите делать это в программном обеспечении с YCbYCr. Я использую Linux и Mesa3D — используйте как минимум версию 23.1.4 — ранее были ошибки, связанные с драйвером ETNAVIV. Используйте OpenGL и запишите свой MDMA в BO GBM, который вы используете в качестве внешней текстуры, а затем используйте шейдер для преобразования из YCbYCr в RGB. Подсказка: формат ARGB прекрасно подходит для одного слова YCbYCr. Бонус: поскольку изображение представляет собой текстуру, вы можете сопоставить его с чем угодно — от просто прямоугольного изображения до обертывания его вокруг фигуры. Это мило. Кроме того, фильтрация текстур работает и может немного улучшить изображение, что удивительно, почти с нулевыми затратами.
Мой кадровый буфер в DRAM содержит три полных изображения, циклически повторяющихся, чтобы избежать каких-либо шансов на разрыв, поскольку отрисовка OpenGL в буфер рендеринга не синхронизирована с захватом кадров камеры. В зависимости от вашей системы вам, возможно, придется проделать весь этот беспорядок за пределами Linux, поскольку существующие драйверы могут вообще не работать - они могут реагировать на ошибку и переполнение, а также на флаги кадров, которые здесь следует просто игнорировать. Я использовал процессор M4, чтобы выполнить здесь тяжелую работу, и OpenGL просто находит изображение с камеры, волшебным образом появляющееся в текстуре. DCMI будет работать с любой длиной строки или количеством строк - при встроенной синхронизации вы получаете данные активной линии (поэтому ваш DMA должен быть настроен для этого), а не синхронизации и не данные между началом и концом HSync. Вы получаете данные активной линии в течение периода вертикальной синхронизации.
Я использую DCMI с TVP5151 (почти идентичным TVP5150) и камерам PAL, а также камерам NTSC.