Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Zynq подключение камеры
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Страницы: 1, 2
ilyaprok
Доброго времени суток!
Я совсем новенький в теме SoC. Есть плата Z-turn и JTAG отладчик, все подружил, попробовал hello world.
Пока читаю книгу ZynqBook.
Есть задача:
подключить камеру MT9V034 к плате Z-turn. Хочу подключить по параллельному интерфейсу (PIXCLK, DATA(9:0), HSYNC, VSYNC), но можно еще по LVDS последовательному интерфейсу. Камера имеет разрешение 752х480 60 фпс, монохромная.
1) Есть ли у кого опыт пользования этими интерфейсами, камера будет в сантиметрах от платы, поэтому скорее всего LVDS помехозащищенность не нужна. И проще всего подключить по параллельному интерфейсу. Так ли это?
2) Далее надо организовать некий контроллер-приемник на стороне PL. Есть ли готовые IP-ядра для этого? В STM32 есть DCMI контроллер, есть ли здесь что то похожее?
3) Надо, чтобы контроллер-приемник передавал принятые байты DMA контроллеру, а он складывал в видеобуфер на стороне DDR. Какой DMA контроллер использовать, который реализован аппаратно в PS или нужно IP ядро?
4) Как организовать связку DMA контроллера и DDR памяти, нужно ли доп ядро DDR контроллера? Какие параметры нужно устанавливать для совместной их работы и как их настроить? После заполнения видеобуфера, надо чтобы сработало прерывание для ядра, чтобы можно было производить обработку, то есть ядро никак не должно участвовать в приеме картинки, такое возможно? Стоит ли писать по байтово в DDR или лучше накопить некую пачку и только потом записать? Какова пропускная способность всей цепи от DCMI контроллера до ячеек DDR памяти, потянет ли реал-тайм запись или нудны промежуточные буферы?
5) Я так понимаю нужно 2 DDR буфера -пока один постепенно заполняется, с другим можно работать, потом они меняются местами, правильно ли думаю? Как организовать доступ ядра к DDR памяти или я просто обращаюсь под выделенное для DDR памяти адресное пространство и DDR контроллер понимает, что это орбащение к DDR памяти и все организовывает сам?
6) После получения кадра, надо отсылать картинку по UDP на комп, где она визуализируется. Хочу писать в FreeRTOS, есть ли готовые функции для приема/отправки UDP пакетов, как они реализованы (блокируемые или по прерываниям)? Как правильно упаковать картинку для передачи по UDP.
7) Еще не понятна схема работы в Vivado и SDK. То есть в Vivado нужно нарисовать саму архитектуру системы, далее сгенерировать некий BSP. А в SDK с помощью этого самого BSP настроить периферию, записью в различные регистры. Правильно я понимаю?
8) Если я использую аппаратный SPI в PS, нужно ли мне генерировать Bitstream? Ведь По идее ресурсы FGPA не используются
9) Как взаимодействовать с кэшем различного уровня? Как правильно с ним работать? Интересует именно в BareMetal и FreeRTOS варианте.
И вообще вопрос как правильно разрабатывать на таком устройстве? То есть как переключаться между SDK и Vivado, в какую память шить? Какие тесты делать? Как лучше отлаживать в SDK или внешними утилитами? Какие подводные камни есть? на что стоит обратить внимание? Очень много настроек в PS, что можно менять и как они повлияют друг на друга? Можно ли часть настроек менять в SDK вместо Vivado или они независимые?
Очень много вопросов.
Надеюсь не нарушил никакие правила и не задал слишком нубских вопросов.
Принимаю любую критику, ссылки на учебники, уроки, советы, наставления. Ответы на любые вопросы, какие сможете или хотите ответить. Заранее спасибо.
RuSTA
Готов выполнить за вознаграждение!
x736C
Цитата(ilyaprok @ Oct 30 2017, 11:57) *
1) Есть ли у кого опыт пользования этими интерфейсами, камера будет в сантиметрах от платы, поэтому скорее всего LVDS помехозащищенность не нужна. И проще всего подключить по параллельному интерфейсу. Так ли это?
Да, это так.

Цитата(ilyaprok @ Oct 30 2017, 11:57) *
6) После получения кадра, надо отсылать картинку по UDP на комп, где она визуализируется. Хочу писать в FreeRTOS, есть ли готовые функции для приема/отправки UDP пакетов, как они реализованы (блокируемые или по прерываниям)? Как правильно упаковать картинку для передачи по UDP.
Посчитайте битрейт. Вероятно, будет сложно реализовать передачу на комп в несжатом виде. Например, через 100 Мбит/c гарантированно не пролезет. Зависит, конечно, от разрешения и частоты смены кадров.
Как правильно упаковать картинку. Зависит от того, чем вы её собираетесь на компьютере отображать. Если своими силами, то просто сложите картинку в пакеты, снабдив служебной информацией начала-конца кадра. Если сторонними плеерами, то есть и стандартные контейнеры. По FreeRTOS есть подфорум, там по сетевым протоколам можно найти массу информации. Мне представляется разумным сжать видеопоток в MJPEG (есть готовые ядра opensource) до разумного битрейта (50-80 Мбит/c). Для стрима по UDP тоже есть доступные ядра, но можно стримить процессором. Многие плееры (например, VLC) спокойно воспроизводят MJPEG по UDP.


Исходный битрейт: 752 * 480 * 60 * 8 = ~170 Мбит/c. В принципе немного. По 1G сетке спокойно можно переслать.
ilyaprok
Цитата
Готов выполнить за вознаграждение!

Выполнение не надо, надо самому обучиться, за сколько вы можете меня проконсультировать и обучить базе, конкретно на этой задаче?
x736C большое спасибо за ответ, уже какие то вопросы закрываются.
Пока самое узкое и непонятное место - это взаимодействие с DRAM, DMA, DCMI. Может вы можете меня послать на верный путь?
sheynmanyu
Цитата(ilyaprok @ Oct 31 2017, 14:41) *
Пока самое узкое и непонятное место - это взаимодействие с DRAM, DMA, DCMI. Может вы можете меня послать на верный путь?

Может, это поможет? https://www.xilinx.com/support/documentatio...ver-IP-zynq.pdf
Сама сейчас грызу...
svedach
Лично с Вами (ТС) связаться можно?
ilyaprok
Цитата(sheynmanyu @ Oct 31 2017, 16:47) *
Может, это поможет? https://www.xilinx.com/support/documentatio...ver-IP-zynq.pdf
Сама сейчас грызу...

Большое спасибо, почитаю на досуге. Сейчас кстати смотрю видео на ютубе https://www.youtube.com/user/mamsadegh2/videos.


Цитата(svedach @ Oct 31 2017, 22:18) *
Лично с Вами (ТС) связаться можно?

Не знаю можно ли тут публиковать свои данные, личное сообщение послать не могу, ну лады. мой мейл ilya94prok@mail.ru
svedach
1) Проще всего подключить по параллельному интерфейсу... Если по LVDS, то придется городить десерилизатор (там скорее всего последовательно данные идти будут).
2) Готовые ядра есть, но лучше писать самому IP-ядро (на мой взгляд), оно должно принимать данные от матрицы и управлять ею, и на выход выдавать поток видео в AXI Stream.
3) Поток AXI Stream нудно подавать на настроенный контроллер DMA, не важно где он будет реализован. Настраивать его удобнее всего процессором, который выделяет память под буфферы в DDR и по прерыванию от IP-ядра управления матрицей сменяет их...

Остальное позже...
ilyaprok
А как соединить IP ядро с конкретным портом, как его сконфигурировать? Есть документ или урок, где это делается?
Вот получается у меня есть справа порты, которым надо назначить конкретный физические выводы. Где об этом почитать?
_Ivan_33
правой кнопкой мыши create port
затем его соединить в констрейнах с физическим пином
ilyaprok
Спасибо за последние ответы.
Вновь прошу помощи.
Данные не проходят блок "Video in to Axi 4 Stream".
Имею камеру MT9V034 данные идут по параллельной шине DATA(7:0), PXCLK, LINE_VALID (активный сигнал - 1), FRAME_VALID (активный сигнал - 1). На вход подаю тактирование я взял с FCLK1 - 13.3333 МГц.
У ядра "Video in to Axi 4 Stream" имеется входы vid_data(7:0), vid_active_video, vid_field_id, vid_hblak, vid_vblank, vid_hsync, vid_vsync, vid_io_in_clk, vid_io_in_ce, vid_io_in_reset.
В документации написано используйте сигналы sync или сигналы blank. Непонятно как из LINE_VALID, FRAME_VALID создать vid_hblak, vid_vblank или vid_hsync, vid_vsync. пробовал по-всякому. Частоту FCLK1 менял в большую и и меньшую сторону.
В Вивадо отладчике пытаюсь посмотреть что приходит на входы и что на выходе блока.
Но отладчик показывает вообще какую то чушь!!! смотрю на осциллограф, там нормальная картинка, как и должно быть.
Что я делаю не так? Кто посоветует.
Может влиять длина проводников на такой частоте (13,3333 МГц)? Около 10 см.
Прочел темы:
https://forums.xilinx.com/t5/DSP-and-Video/...ace/td-p/517557
https://forums.xilinx.com/t5/Zynq-All-Progr...ht/false#M15677
https://forums.xilinx.com/t5/Zynq-All-Progr...-IP/td-p/531275



Вот запись с лог. анализатора
1

2
svedach
Оставляю для Вас личное IP-ядро с исходниками, которое работает с видео-декодерами (правда только с компонентой яркости).



Сигналы DE и HS в Вашем случае можно объединить. Отдаю с исходниками - разберетесь, будут вопросы - буду отвечать...
ilyaprok
Цитата(svedach @ Nov 14 2017, 22:47) *
Оставляю для Вас личное IP-ядро с исходниками, которое работает с видео-декодерами (правда только с компонентой яркости).



Сигналы DE и HS в Вашем случае можно объединить. Отдаю с исходниками - разберетесь, будут вопросы - буду отвечать...

Огромное спасибо! biggrin.gif Сейчас буду пробовать.

С вашим ядром уже какие то данные идут!
Это то что на входе:

Это то что на выходе:

Данные все время меняются, то есть что то идет!
Вот только я не понял - почему сигналы тактирования в нуле? ila2 - это то что на входе тактируется PXCLK - 13.3333 МГц. А ila1 - это то что на выходе тактируется FCLK0 - 100 Мгц.
В этом самом дебагере не получилось запуститься по тригеру никаким сигналом (пробовал по переднему фронту TVALID, TREADY, TLAST). Нормально ли это? То есть я так понимаю эти сигналы зависят от следующего ядра (у меня AXI DMA)
Еще не получалось долго проивезти имплементацию, ругался на vid_io_in_clk (это который PXCLK - 13.333 МГЦ), я в Constraint прописал set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets vid_io_in_clk_IBUF].
Может ли это как то помешать?
А так большое спасибо за помощь!
Еще вопрос - как определять начало кадра и иницировать транзакцию DMA? Я пока вижу так - подключить сигнал tuser к прерыванию - в обработчике прерывания иницировать передачу DMA - в первый раз. А далее иницировать уже в прерывании по DMA. Как посоветуете?
svedach
Добрый день. Вы уверены, что правильно назначили сигналы на пины? Может ошибка где-то закралась... Тактовые частоты на сигналы дебаггера не заводят - это плохая практика... У них цепи распространения разные и в Вашем случае синтезатору приходится перекидывать клоковую цепь на сигнальную - от этого и может ругаться.
Посмотрите осциллом - выходит ли тактовая на камеру... посмотрите, не нужно ли разрешать работу камеры где-нибудь в ее настройках... Камера скорее всего имеет встроенный PLL - посмотрите, какие настройки ему выставлены.
Начало кадра (в соответствии с AXSI Stream for Video) - один строб на сигнале TUSER. Я работаю с DMA так: процессором сконфигурировал его для приема линии, ядро отдало линию - получаю прерывание от DMA о том, что линия уложена в память, даю команду ждать следующую и т.д. Но тут как кому удобнее. Дело в том, что DMA определяет конец данных по сигналу TLAST - а это (по AXSI Stream for Video) сигнал окончания строки, по этому мне так удобнее.
_Ivan_33
Еще такая тема с чушью лог.анализатора - там в списке ядер их 2 штуки - system ila и обычные. У меня были глюки с системным. Попробуйте заменить.

Я весь дизайн не смотрел - но есть 2 пути инициализации транзакции - первый это самописный мастер, который передает данные в область памяти DDR и дергает прерывание процессору.
Второй это ядро по-моему AXI VDMA - с ним не работал, надо курить.

А процессор работает на бареметал, пингвинах или фриртос или что?

Пропускная способность AXI от PL до DDR через AXI_HP порт составляет 1200 МБайт в секунду - это частота 150 МГц при ширине шины в 8 байт. У себя делал такое, правда на 100 МГц у меня получилось грубо говоря на 1000 слов 1100 тактов передачи - т.е. на 10% ниже. Таких портов 4 штуки...

ilyaprok
Цитата(svedach @ Nov 15 2017, 11:07) *
Добрый день. Вы уверены, что правильно назначили сигналы на пины? Может ошибка где-то закралась...

Добрый, спасибо за ответ)
Сигналы AVInClk, AVInVS, AVInHS точно правильно назначил на физические ножки. С данными если и будет путанница, то потом разберусь.
Цитата(svedach @ Nov 15 2017, 11:07) *
Тактовые частоты на сигналы дебаггера не заводят - это плохая практика... У них цепи распространения разные и в Вашем случае синтезатору приходится перекидывать клоковую цепь на сигнальную - от этого и может ругаться.
Посмотрите осциллом - выходит ли тактовая на камеру...

Вот с клоковыми сигналами я не до конца понял. Мою камеру надо тактировать извне от 13-27 МГц. Соответственно этот клок надо вывести из Zynq. Я просто вывел тактовую FCLK1 - 13.333 МГц на физический пин. С этим проблем нет. Осциллографом глянул - такт есть.
Синтезатор ругается на физическую привязку к пину (vid_io_in_clk) сигнала AVInClk, то есть на входной клок от камеры. Я в констрейнах прописал set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets vid_io_in_clk_IBUF]. Он перестал ругаться. Но не притянет ли это дополнительные проблемы?
А как тогда в дебагере посмотреть как данные проходят, если не привязываться к клоковым сигналам?
Цитата(svedach @ Nov 15 2017, 11:07) *
посмотрите, не нужно ли разрешать работу камеры где-нибудь в ее настройках... Камера скорее всего имеет встроенный PLL - посмотрите, какие настройки ему выставлены.
Начало кадра (в соответствии с AXSI Stream for Video) - один строб на сигнале TUSER. Я работаю с DMA так: процессором сконфигурировал его для приема линии, ядро отдало линию - получаю прерывание от DMA о том, что линия уложена в память, даю команду ждать следующую и т.д. Но тут как кому удобнее. Дело в том, что DMA определяет конец данных по сигналу TLAST - а это (по AXSI Stream for Video) сигнал окончания строки, по этому мне так удобнее.

Камера тактируется извне... Сигналы связанные с AXI Stream Master - будут зависеть от принимающего блока (у меня AXI DMA), я имею ввиду, что пока я не сконфигурирую DMA - он не будет принимать данные, и соответсвенно - шина будет статична? или данные независимо от DMA будут идти вникуда?
Второй вопрос - как мне поймать начало кадра? По сигналу TUSER - но если шина статична - то сигнал TUSER не появится, так ли это? В дебагере в предыдущем посте я вижу именно, что шина не работает, данные статичны.
svedach
Цитата
Синтезатор ругается на физическую привязку к пину (vid_io_in_clk) сигнала AVInClk

Все правильно, значит пин не клоковый... Пока это не страшно.

Цитата
я имею ввиду, что пока я не сконфигурирую DMA - он не будет принимать данные, и соответсвенно - шина будет статична

Именно так!

Но Вы можете проанализировать поведение внутренних цепей ядра...

Про тактовые на дебагере - не надо их заводить для просмотра как сигнал... Просто знайте, что они есть... Если дебагер показывает времянку - он уже от чего-то тактируется...
ilyaprok
Цитата(_Ivan_33 @ Nov 15 2017, 13:12) *
Еще такая тема с чушью лог.анализатора - там в списке ядер их 2 штуки - system ila и обычные. У меня были глюки с системным. Попробуйте заменить.

Спасибо за помощь)
Я так понял у меня обычные ila. так как нигде не видно приставки system. Но хотелось бы удостоверится, где посмотреть?
Цитата(_Ivan_33 @ Nov 15 2017, 13:12) *
Я весь дизайн не смотрел - но есть 2 пути инициализации транзакции - первый это самописный мастер, который передает данные в область памяти DDR и дергает прерывание процессору.
Второй это ядро по-моему AXI VDMA - с ним не работал, надо курить.

Да я еще слишком неопытен, чтобы писать свое ядро, поэтому использую обычный AXI DMA, возможно возьму AXI VDMA. По идее мне надо просто сложить данные с камеры в DRAM. Но надо как то поймать начало кадра, чтобы первые данные в DRAM были именно с первого пикселя, а не с середины кадра.
Цитата(_Ivan_33 @ Nov 15 2017, 13:12) *
А процессор работает на бареметал, пингвинах или фриртос или что?

Сейчас работает на бареметалл, по мере усложнения проекта перейду на FreeRTOS, так как имел с ней опыт на STM32.
Цитата(_Ivan_33 @ Nov 15 2017, 13:12) *
Пропускная способность AXI от PL до DDR через AXI_HP порт составляет 1200 МБайт в секунду - это частота 150 МГц при ширине шины в 8 байт. У себя делал такое, правда на 100 МГц у меня получилось грубо говоря на 1000 слов 1100 тактов передачи - т.е. на 10% ниже. Таких портов 4 штуки...

Да я думаю с пропускной способностью проблем не возникнет - камера 752*480 пикселей, монохромная, то есть один пиксел - 1 байт. всего 752*480*1 = 360 960 байт - один кадр. Хочу разогнать до 60 фпс. Итого 21 657 600 байт в секунду. Итого около 20 Мбайт/сек.

Цитата(svedach @ Nov 15 2017, 13:45) *
Все правильно, значит пин не клоковый... Пока это не страшно.


Именно так!

Но Вы можете проанализировать поведение внутренних цепей ядра...

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

Вот спасибо еще раз, вы меня прям сильно выручаете!
Тогда у меня вопрос - как отследить начало кадра?
Есть такой вариант - сначала настроить DMA, чтобы он ожидал данных. А потом подать клок на камеру. тогда автоматом первые пиксел кадра будет первым в памяти DRAM?
А можно в DMA длину всего кадра заказать? а не одной строки?
И еще вопрос - лучше самому в регистры записывать или использовать готовые функции из BSP?
_Ivan_33
Ну тема такая - для бареметал все просто - у вас есть физический адрес буфера в памяти, его можно сделать кольцевым или несколько штук. Дальше передаете этот адрес ядру ДМА, он передает данные, дергает прерывание и вы ему адрес заменяете или он сам показывает адрес последней транзакции.
Если будут пингвины, то нужно маппировать физические адреса на виртуальные и гуглите nmap
НАсчет фриртос не знаю.
Сам делаю похожую задачу))

Мастер акси 4 не такой сложный, тем более что вам нужно только сделать запись. Начните с передачи слова, потом добавьте счетчик слов и все норм

svedach
Цитата
А можно в DMA длину всего кадра заказать? а не одной строки?

Это нарушит стандарт AXI Stream for Video!

Можете отдельно ответвить от шины TUSER и завести его как прерывание. В софтварной части Вы должны распределить память под кадр, в начале работы указываете ДМА первый адрес и длину строки - он положит туда одну строку (не обязательно первую, но это не срашно - см. далее), по прерыванию от ДМА задаете ему новый адрес - смещенный на длину строки первый, опять запускаете его записью длины строки, опять прерывание и т.д.
НО!!!! По приходу прерывания от TUSER (прокинутого как прерывание) сбрасываете указатель на начало распределенной памяти - таким образом следующая запрошенная строка ОБЯЗАТЕЛЬНО будет первой в распределенной области (и естественно первой в кадре...) т.е. все совпадет!
ilyaprok
Цитата(svedach @ Nov 15 2017, 14:14) *
Это нарушит стандарт AXI Stream for Video!

Можете отдельно ответвить от шины TUSER и завести его как прерывание. В софтварной части Вы должны распределить память под кадр, в начале работы указываете ДМА первый адрес и длину строки - он положит туда одну строку (не обязательно первую, но это не срашно - см. далее), по прерыванию от ДМА задаете ему новый адрес - смещенный на длину строки первый, опять запускаете его записью длины строки, опять прерывание и т.д.
НО!!!! По приходу прерывания от TUSER (прокинутого как прерывание) сбрасываете указатель на начало распределенной памяти - таким образом следующая запрошенная строка ОБЯЗАТЕЛЬНО будет первой в распределенной области (и естественно первой в кадре...) т.е. все совпадет!

Спасибо. Да TUSER завел как прерывание, тоже так хотел сделать. Теперь раз мысли совпали, так и сделаю
ilyaprok
Опять нужна помощь(
Данные c ядра AV2AXISV_0 дальше не идут. DMA не дает сигнал tready. Я так понимаю в этом проблема.
Но почему он не дает сигнал готовности принять?
Читал несколько раз даташит на DMA AXI ядро. Написал в ручную регистры, которые надо заполнять. проверил - заполняются правильно. DMA стартует и останавливается (биты в нужных регистрах устанавливаются и сбрасываются). Но по факту ничего не происходит, в прерывание не заходит. Ни в DMA, ни в TUSER. То есть мое подозрение, что слабое место в связке между AV2AXISV_0 и DMA.
Вот дебаггер:

Вот код
Код
void DMA_Start(uint32_t dest, uint32_t length)
{
    uint32_t tmp;

    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x48, dest);
    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x58, length);

    tmp = Xil_In32(XPAR_AXI_DMA_0_BASEADDR + 0x30);
    //Start DMA
    tmp |= 0x0001;
    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x30, tmp);
}
void DMA_Init(void)
{
    uint32_t tmp;

    tmp = Xil_In32(XPAR_AXI_DMA_0_BASEADDR + 0x30);

    //Enable Interrupt
    tmp |= 0x1000;

    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x30, tmp);


}
void DMA_Stop(void)
{
    uint32_t tmp;

    tmp = Xil_In32(XPAR_AXI_DMA_0_BASEADDR + 0x30);

    //Disable DMA
    tmp &=~0b101;

    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x30, tmp);

    int delay;
    for(delay = 0; delay < 5000; delay++);

}
void DMA_TransferEnd_Handler(void)
{
    uint32_t tmp;
    printf("DMA_TransferEnd_Handler\r\n");
    //clear inter;
    tmp = Xil_In32(XPAR_AXI_DMA_0_BASEADDR + 0x34);
    tmp |= 0x1000;
    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x34, tmp);

...
}
int main()
{
...
    DMA_Stop();
    DMA_Init();
    DMA_Start(0x01000000, 752);
...
svedach
Для быстрой проверки: отключите TREADY от DMA и подайте на него "1". Посмотрите как работает шина!
Я дал Вам ядро, что бы разобраться, возможно сходу с Вашей камерой оно и не будет работать...
Обратите внимание на модуль AVInput внутри ядра - там есть константы, они для видеодекодеров, для Вашей камерв могут не подойти.
Обратите внимание на то, как используются и комбинируются входные сигналы.
Будет не понятно - спрашивайте.


Код
//Сбрасываем ядро AXI DMA
    RegVal    = 0x04;
    Xil_Out32(XPAR_VIDEODMA_BASEADDR + 0x30, RegVal);
    //Дожидаемся окончания сброса ядра
    while(RegVal & (1 << 2))
    {
        RegVal    = Xil_In32(XPAR_VIDEODMA_BASEADDR + 0x30);
    }
    //Инициализируем AXI DMA
    RegVal    = Xil_In32(XPAR_VIDEODMA_BASEADDR + 0x30);
    RegVal    = RegVal | 0x1001;
    Xil_Out32(XPAR_VIDEODMA_BASEADDR + 0x30, RegVal);
    RegVal    = Xil_In32(XPAR_VIDEODMA_BASEADDR + 0x30);
    xil_printf("AXI DMA control register value: %x\n\r", RegVal);
    RegVal    = Xil_In32(XPAR_VIDEODMA_BASEADDR + 0x34);
    xil_printf("AXI DMA status register value: %x\n\r", RegVal);


Инициализация DMA

Код
//Устанавливаем обработчик прерывания приема очередной линии
    Status            = XScuGic_Connect(INTRCtrl, XPAR_FABRIC_VIDEODMA_S2MM_INTROUT_INTR, (Xil_InterruptHandler)_Sensor_Line_Ready_HANDLER, NULL);
    if (Status != XST_SUCCESS)    return XST_FAILURE;


Установка прерывания (контроллер прерываний должен быть уже настроен)

Код
//Разрешаем прерывания
    XScuGic_Enable(INTRCtrl, XPAR_FABRIC_VIDEODMA_S2MM_INTROUT_INTR);


Разрешение прерывания от DMA



Код
//Метод обработки прерываний
void    _Sensor_Line_Ready_HANDLER(void)
{
    u32        RegValue;
    //Сбрасываем флаг прерывания
    RegValue            = Xil_In32(XPAR_VIDEODMA_BASEADDR + 0x34);
    RegValue            = RegValue | 0x1000;
    Xil_Out32(XPAR_VIDEODMA_BASEADDR + 0x34, RegValue);
    //Запрашиваем очередную порцию данных
    if (Sensor_Line_Idx < LinesInFrame)
    {
        Xil_Out32(XPAR_VIDEODMA_BASEADDR + 0x48, (unsigned int)Frame[Sensor_Line_Idx]);
        Xil_DCacheFlushRange((unsigned int)Frame[Sensor_Line_Idx], RF627_Config.Streams_Config.Video_PacketSize);
        Xil_Out32(XPAR_VIDEODMA_BASEADDR + 0x58, RF627_Config.Streams_Config.Video_PacketSize);
        //Икрементируем номер линии
        Sensor_Line_Idx += 1;
    }else
    {
        FrameReady        = 255;
        Sensor_Line_Idx    = 0;
    }
};


Обработка прерывания с запросом очередной порции данных
ilyaprok
Цитата(svedach @ Nov 15 2017, 22:29) *
Обратите внимание на модуль AVInput внутри ядра - там есть константы, они для видеодекодеров, для Вашей камерв могут не подойти.
Обратите внимание на то, как используются и комбинируются входные сигналы.
Будет не понятно - спрашивайте.

Попробовал tready подтянуть к 1. Вот скрин дебагера:

TUSER - вообще странно появляется, не привязан ни к чему.
Если я поменяю константы в файле AVInput.v на нужные, заработает ли правильно ядро? Не понятно что за параметры F1_START_LN, F2_START_LN, F1_END_LN, F2_END_LN ? никак не могу понять, у меня есть сигналы FRAME_VALID, LINE_VALID - их подключать к сигналам AVInVS и AVInHS соответсвенно? или они не связаны?
Внутри даташита на MT9V034 есть такая таблица:

Есть датаграмма снятая с физических портов камеры:

Если я перепишу параметры в AVInput, заработает ядро? Или тут надо логику переписывать? Может тогда проще по LVDS линии соединится?
ilyaprok
Вообщем вернулся к первоначальному варианту с VideoIn To AXI4 Stream.
сигналы с камеры завел так:
hblank = ~LINE_VALID
vblank = ~FARME_VALID
active_video = LINE_VALID&FARME_VALID
tready на AXI шине поставил в 1.
Снял датаграммы:
Это то что на входе ядра - сигналы с камеры

Это то что на выходе ядра на AXI шине

Кажется что работает.
Теперь соединил tready к DMA.
Сигналы с камеры по прежнему идут.
А на АКСИ шине ничего нет, сигнал tready из DMA все блокирует.
svedach
tvalid очень странно себя ведет..

Если ДМА блокирует - значит количество принятых данных не совпадает с запрошенным! Посмотрите статус ДМА - там в этом случае должна быть выставлена ошибка.
ilyaprok
Добился того, что DMA делает несколько транзакций - всегда разное кол-во от 1 до 11 примерно и возникает внутренняя ошибка DMA Internal Error. This error occurs if the buffer length specified in the fetched descriptor is set to 0. Also, when in Scatter Gather Mode and using the status app length field, this error occurs when the Status AXI4-Stream packet RxLength field does not match the S2MM packet being received by the S_AXIS_S2MM interface. Я так понимаю из-за того, что размер пакета измеряемый сигналом TLAST не соответсвует (больше/меньше) длине в регистре 0х58.
Я делаю так:
Код
main(void)
{
...
DMA_Start(START_ADRR_FRAME, 752);
...
}
void DMA_TransferEnd_Handler(void)
{
    u32        RegValue;
    //Сбрасываем флаг прерывания
    RegValue            = Xil_In32(XPAR_AXI_DMA_0_BASEADDR + 0x34);
    RegValue            = RegValue | 0x1000;
    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x34, RegValue);
    //Запрашиваем очередную порцию данных
    if (cntRow < 480)
    {
        AddrDst += 752;
        Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x48, AddrDst);
        //Xil_DCacheFlushRange(AddrDst, 752);
        Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x58, 752);
        //Икрементируем номер линии
        cntRow += 1;
    }else
    {
        cntRow    = 0;
    }
    printf("Row = %d\r\n", cntRow);
}

То есть в прерывания заходит, но потом спустя несколько транзакций происходит эта ошибка. Я использую обычный AXI DMA. Сейчас попробую AXI VDMA.
svedach
AXI VDMA можете не пробовать - не тратьте время....
Разберитесь с сигналами - они явно не в порядке...
ilyaprok
Цитата(svedach @ Nov 16 2017, 15:16) *
AXI VDMA можете не пробовать - не тратьте время....
Разберитесь с сигналами - они явно не в порядке...

хорошо, спасибо. А что не так с сигналами? Как должно выглядеть?

Если запустить лог анализатор в вивадо на по фронту TREADY и при этом запустить прогу в SDK, то пооучается вот это:

В SDK при этом DMA совершает 1-11 транзакций по 752 байта, и останавливается по внутренней ошибке.
То что я совершаю транзакции по 752 байта - эта одна линия, это нормально? TUSER вообще никогда не появляется. Изменяя 752 байта в большую сторону, ошибок не возникает, но в лог анализаторе такая же картина.
svedach
Я давал Вам свое ядро, что бы Вы могли там сигнальчики посмотреть и если что - обсудить... Вы уверены, что длительность строки у Вас правильная (а не плавает из-за каких-либо факторов)?
Все-таки рекомендую Вам сначала удостовериться, что все сигналы от камеры правильные и Вы четко понимаете их длительности и соотношения!
Нужно было бы добавить счетчик по стробу данных в строке и посмотреть, сколько их реально приходит - не плавает ли... Как соотносятся стробы кадра и строки и т.д.
ilyaprok
Цитата(svedach @ Nov 16 2017, 16:22) *
Я давал Вам свое ядро, что бы Вы могли там сигнальчики посмотреть и если что - обсудить... Вы уверены, что длительность строки у Вас правильная (а не плавает из-за каких-либо факторов)?
Все-таки рекомендую Вам сначала удостовериться, что все сигналы от камеры правильные и Вы четко понимаете их длительности и соотношения!
Нужно было бы добавить счетчик по стробу данных в строке и посмотреть, сколько их реально приходит - не плавает ли... Как соотносятся стробы кадра и строки и т.д.

Понял.
Сейчас еще раз проверил в лог. анализаторе в Вивадо. Длительность строки проверил ровно 752 такта. Как проверял - 1 варинат: по тригеру FRAME_VALID запускал лог. анализатор. по маркерам точно выставлял границы фронтов сигнала LINE_VALID, в этой же датаграмме проверил 4 пачки. 2 вариант - также по тригеру FRAME_VALID запускал лог. анализатор выставил маркеры на гранциах фронтов сигнала LINE_VALID и раз 10 перезапускал лог. анализатор, смотрел, чтобы границы фронтов не съезжали от маркеров. Теперь я уверен, что LINE_VALID четко 752 такта. Также проверил промежуток от начала фронта FRAME_VALID до первого фронта LINE_VALID - четко 71 такт. Все как по даташиту на камеру.
Вот скрины лог анализатора
1

2

В прошлом посте я показывал картинку из даташита на камеру, там расписаны все тайминги, продублирую:

То есть сигналы с камеры четкие.
какие сигналы посоветуете еще посмотреть?


Еще такой вопрос, какое из ядер надо использовать? И не повлияют ли внутренние параметры, которые вы упоминали?
svedach
Используйте AV2AXISV.
Посмотрите, как формируются сигналы внутри AVInput - в Вашем случае там надо будет подправить логику управления записью в буфферы и чтение из них...
ilyaprok
Хотя еще раз проверил, в лог анализаторе, некоторые строки разной длины, где то в середине кадра... буду проверять

Цитата(svedach @ Nov 16 2017, 18:32) *
Используйте AV2AXISV.
Посмотрите, как формируются сигналы внутри AVInput - в Вашем случае там надо будет подправить логику управления записью в буфферы и чтение из них...

Спасибо, вот эти пареметры тоже надо поправить?
Цитата
parameter ACT_VID_LEN = 11'd1723,
parameter H_BLANK = 11'd283,
parameter F1_START_LN = 10'd25,
parameter F2_START_LN = 10'd337,
parameter F1_END_LN = 10'd313,
parameter F2_END_LN = 10'd625



А что означают последние 4 параметра?
Цитата
always @(posedge AVOutClk)
begin
ValuesCounter <= (AVInHSReg) ? (ValuesCounter + 1) : 0;
InBuff1WrE <= (InBuffSel == 0) && (ValuesCounter > 282-12) && (ValuesCounter < 1722-12) && YVld;
InBuff2WrE <= (InBuffSel == 1) && (ValuesCounter > 282-12) && (ValuesCounter < 1722-12) && YVld;
end

Это тоже надо поправить?
А вообще это надо мне тогда день выделить, чтобы разобраться, завтра посмотрю подробно, буду разбираться. Спасибо.
ilyaprok
Действительно примерно 1 из 5 случаев в лог. анализаторе Вивадо кол-во тактов линии LINE_VALID не 752, бывает 751, 749 и т.д. Это Связано с железом? или это глюки Вивадо? камеру менял, провода сократил, частоту менял 13,33 и 26,6 Мгц пропобовал, все одинаково.
svedach
Тут сложнее: это может быть проблема дебаггера, если Вы тактируете захват сигнала одной тактовой (например AXI), а сигнал передается на другой (частоте камеры), могут быть не правильно настроены входные пины (напряжения, подтяжки, терминаторы), может быть проблема железа - плохо пропаяно, или еще что-то такое. Можете выложить фото связи камеры с платой?
В любом случае надо сначала решить эту проблему, а потом двигаться дальше.
ilyaprok
У меня получается два отладочный ядра. Одно тактируется от AXI 100 Мгц. Для отладки АКСИ шины. Второе ядро тактируется от входящего с камеры клока 13,333 Мгц. Заметил, что никогда не бывает больше чем 752 такта, всегда либо ровно, либо чуть меньше. Доходило даже до 740 тактов вместо 752. Может физические пины не подходят, надо другие брать. Осциллограф у меня простой от USB, такие частоты на грани видит. А какие подтяжки нужны, может токоограничивающий резистор поставить на такт камеры?


Flip-fl0p
Ну хоть бы трубки термоусадочные на контакты надели, ну нельзя же так работать ! А если отвалится и замкнет что-то ?
Я вот всё смотрю и не могу понять, а куда данные с камеры выводятся потом ? На монитор через HDMI ?
svedach
Дааа, с таким монтажем далеко не уедем... Можете резисторы на землю (PULLDOWN) в настройках пинов ПЛИС выставить попробовать...
Напряжения согласованы (какие напряжения на пинах камеры и каким напряжением питается банк ПЛИС)?
ilyaprok
Каюсь монтаж ужасен, это временный вариант, пока нужный разъем не пришел, чтобы нормально плату развести.
Данные с камеры не выводятся, смотрю в отладчике в DDR и в отладчике в Вивадо, пока нормальные сигналы не получу, нечего выводить.
Цитата
set_property IOSTANDARD LVCMOS33 [get_ports {vid_data[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vid_data[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vid_data[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vid_data[1]}]

set_property IOSTANDARD LVCMOS33 [get_ports {vid_data[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vid_data[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vid_data[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vid_data[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports vid_line]
set_property IOSTANDARD LVCMOS33 [get_ports vid_frame]
set_property IOSTANDARD LVCMOS33 [get_ports vid_io_in_clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk_cam]

set_property PACKAGE_PIN T11 [get_ports {vid_data[0]}]
set_property PACKAGE_PIN T10 [get_ports {vid_data[1]}]
set_property PACKAGE_PIN T12 [get_ports {vid_data[4]}]
set_property PACKAGE_PIN U12 [get_ports {vid_data[5]}]
set_property PACKAGE_PIN U13 [get_ports {vid_data[2]}]
set_property PACKAGE_PIN V13 [get_ports {vid_data[3]}]
set_property PACKAGE_PIN V12 [get_ports {vid_data[6]}]
set_property PACKAGE_PIN W13 [get_ports {vid_data[7]}]

set_property PACKAGE_PIN T14 [get_ports vid_line]
set_property PACKAGE_PIN T15 [get_ports vid_frame]
set_property PACKAGE_PIN P14 [get_ports vid_io_in_clk]
set_property PACKAGE_PIN Y14 [get_ports clk_cam]

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]

Осциллографом уровни около 3,3 В, насколько позволяет посмотреть осцил.
Еще заметил, что если оставить только линии питания, LINE_VALID, FRAME_VALID, PXCLK, SCLK, и убрать все линии данных - то тактов ровно 752, если добавить еще 4 линии данных - то такты опять срываются.
PullDown в constraint сделать? А что за команда, не подскажите? set_property PULLDOWN TRUE [get_ports {vid_data[0]}] ?
Flip-fl0p
Тогда вопрос. А так ли необходимо применять процессор для приёма данных ?
ilyaprok
Цитата(Flip-fl0p @ Nov 17 2017, 00:21) *
Тогда вопрос. А так ли необходимо применять процессор для приёма данных ?

В идеале вообще не применять проц, в идеале надо, чтобы данные автоматом складывались в DRAM. Но мне проще чтобы частично проц участвовал. Но суть не в этом же, я так понял, чт осигналы с камеры почему то не очень качественные...
Flip-fl0p
Цитата(ilyaprok @ Nov 16 2017, 22:50) *
В идеале вообще не применять проц, в идеале надо, чтобы данные автоматом складывались в DRAM. Но мне проще чтобы частично проц участвовал. Но суть не в этом же, я так понял, чт осигналы с камеры почему то не очень качественные...

Для начала сделать нормальный монтаж.
Я бы вообще всё принимал при помощи ПЛИС. Организовал мост между ПЛИС и памятью на стороне CPU, которую бы использовал как кадровый буфер.
А если осциллографом глянуть фронты сигналов, они не слишком пологие ?
ilyaprok
Цитата(Flip-fl0p @ Nov 17 2017, 00:55) *
Для начала сделать нормальный монтаж.
Я бы вообще всё принимал при помощи ПЛИС. Организовал мост между ПЛИС и памятью на стороне CPU, которую бы использовал как кадровый буфер.

Так и есть у меня проц участвует только в настройке DMA и в прерываниях настраивает следующую транзакцию. Вы это имеете ввиду?
Осциллографом не могу посмортеть - я бы и рад , но мой осилл слишком слабый, не видит он такие частоты адекватно.

Еще вопрос насчет отладки. Что нибудь меняю, в блок диаграмме или в контстрейнах. Далее прохожу всю цепочку - синтез, имплементация, битсрим. Если до этого лог. анализатор работал, то после новой комплиляции и заливки. Дебагер либо показывает ошибки, типа invalid <T> vector что то такое, либо No content в окне дебагера, либо ядер вообще не видет. Что я делаю не так? Если что то менять, как правильно проходить всю цепочку, чтобы отладчик не рушился?
Flip-fl0p
Цитата(ilyaprok @ Nov 16 2017, 23:46) *
Так и есть у меня проц участвует только в настройке DMA и в прерываниях настраивает следующую транзакцию. Вы это имеете ввиду?
Осциллографом не могу посмортеть - я бы и рад , но мой осилл слишком слабый, не видит он такие частоты адекватно.

Еще вопрос насчет отладки. Что нибудь меняю, в блок диаграмме или в контстрейнах. Далее прохожу всю цепочку - синтез, имплементация, битсрим. Если до этого лог. анализатор работал, то после новой комплиляции и заливки. Дебагер либо показывает ошибки, типа invalid <T> vector что то такое, либо No content в окне дебагера, либо ядер вообще не видет. Что я делаю не так? Если что то менять, как правильно проходить всю цепочку, чтобы отладчик не рушился?

Я правильно понимаю что модуль v_vid_in_axi4s_0 находится на стороне FPGA ?
Если да, то каким образом обеспечивается правильный приём внешних данных ? Иными словами есть немалое подозрение, что проблема с метастабильностью из-за неправильного приёма/синхронизации внешних данных, асинхронных по своей природе с FPGA.
ilyaprok
Цитата(Flip-fl0p @ Nov 17 2017, 10:04) *
Я правильно понимаю что модуль v_vid_in_axi4s_0 находится на стороне FPGA ?
Если да, то каким образом обеспечивается правильный приём внешних данных ? Иными словами есть немалое подозрение, что проблема с метастабильностью из-за неправильного приёма/синхронизации внешних данных, асинхронных по своей природе с FPGA.

Да правильно. У этого ядра есть два входных клока - один для внешнего интерфейса, как раз с камеры PIXCLK - 13,333 МГц. Есть тактирование для AXI шины - в моем случае 100 МГц. Этот блок расчитан для такой работы. Я так понимаю, что то типа асинхронного FIFO. Поэтому с этим проблем не должно быть.
Но проблема в том, что сами данные с камеры еще до поступления в v_vid_in_axi4s_0 какие то неправильные. Почему то теряются такты. То есть вместо 752 - 751, 749 тактов. Причем это происходит когда подключена линия данных. когда ее нет - то сигнал LINE_VALID ровно 752 такта.
Я еще раз проверю - попробую тактировать камеру от кварца, попробую тактирвать модуль от FPGA напрямую, без прослойки камеры, надо понять - где теряются такты, на линии SCLK (это линия от ZYNQ для тактирования камеры), на линии PIXCLK(это линия от камеры, это просто инвертирванный SCLK) или сам сигнал LINE_VALID - где то завален фронт.
Попробую у знакомых попросить осцилл и посмотреть.
Отпишусь сюда.
А сам лог. анализатор Vivado - может глотать такты?
Есть еще такая строчка у меня set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets vid_io_in_clk_IBUF] Без нее вивадо ругается на этапе имплементации:
Цитата
[Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override this clock rule.
< set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets vid_io_in_clk_IBUF] >

vid_io_in_clk_IBUF_inst (IBUF.O) is locked to IOB_X1Y88
and vid_io_in_clk_IBUF_BUFG_inst (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y31

Может из-за этого такты теряются?
Flip-fl0p
Цитата(ilyaprok @ Nov 17 2017, 15:56) *
Но проблема в том, что сами данные с камеры еще до поступления в v_vid_in_axi4s_0 какие то неправильные. Почему то теряются такты. То есть вместо 752 - 751, 749 тактов. Причем это происходит когда подключена линия данных. когда ее нет - то сигнал LINE_VALID ровно 752 такта.

Скорее всего как раз дело в неправильном приёме данных.
Обратите внимание на страницу 35 даташита на камеру. Там Th и Ts всего по 14 нс. Велика вероятность того, что либо клок где-то в ПЛИС задерживается, либо данные. Нужны правильные входные констрейны.
toshas
Vivado ILA может работать некорректно если частота jtag сравнима с частотой на которой ведется захват.
https://forums.xilinx.com/t5/Simulation-and...p/760288#M18214
Кроме того, если сама по себе частота jtag высокая тоже может сбоить
https://forums.xilinx.com/t5/Welcome-Join/i...-p/425710#M8730
так что поставьте "с запасом" 3 или 6 МГц.

Когда вы отключили линии данных, проект заработал ? На экране по идее должен был быть просто черный квадрат.
ilyaprok
Цитата(Flip-fl0p @ Nov 17 2017, 18:49) *
Скорее всего как раз дело в неправильном приёме данных.
Обратите внимание на страницу 35 даташита на камеру. Там Th и Ts всего по 14 нс. Велика вероятность того, что либо клок где-то в ПЛИС задерживается, либо данные. Нужны правильные входные констрейны.

Спасибо за подсказку, да я посмотрел. Но я так полагаю 14 нс - это для максимальной частоты тактирования 27 МГц, при частоте 13,3 МГц - минимальные Th и Ts около 30 нс. По идее входящие с камеры сигналы идут только в одно ядро на прием, то есть я хочу сказать, что этот клок привязан к узкой области внутри кристалла и не должен затрагивать много цепей и терять синхронизацию. Но я лишь могу на это надеятся.
Может входящий клок с камеры перемапить на другой пин, потому что Вивадо ругается без этой директивы set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets vid_io_in_clk_IBUF], а из-за нее возможно теряются такты? Может такое быть?


Цитата(toshas @ Nov 17 2017, 23:22) *
Vivado ILA может работать некорректно если частота jtag сравнима с частотой на которой ведется захват.
https://forums.xilinx.com/t5/Simulation-and...p/760288#M18214
Кроме того, если сама по себе частота jtag высокая тоже может сбоить
https://forums.xilinx.com/t5/Welcome-Join/i...-p/425710#M8730
так что поставьте "с запасом" 3 или 6 МГц.

Вот интересное замечание, спасибо. действительно частота JTAG 15 МГц. Частоту поменял - ILA перестал выдавать ошибки! Спасибо большое!!!
Цитата(toshas @ Nov 17 2017, 23:22) *
Когда вы отключили линии данных, проект заработал ? На экране по идее должен был быть просто черный квадрат.

Хм, надо проверить. Спасибо. Отпишусь попозже
Flip-fl0p
Цитата(ilyaprok @ Nov 17 2017, 21:50) *

На сколько я смог разобраться, в Xilinx можно с IO пинов завести сигнал в клоковый буфер. Посмотрите, может будет толк.
ilyaprok
Цитата(toshas @ Nov 17 2017, 23:22) *
Когда вы отключили линии данных, проект заработал ? На экране по идее должен был быть просто черный квадрат.


LINE_VALID четко 752 такта. На линии данных FF. Подсоединяю 4 линии данных , такты теряются.
обратно убираю все линии данных. Но в программе после перегона 1-2 строк у DMA внутренняя ошибка. То есть DMA даже не может всю картинку в память перслать.


Цитата(Flip-fl0p @ Nov 18 2017, 00:23) *
На сколько я смог разобраться, в Xilinx можно с IO пинов завести сигнал в клоковый буфер. Посмотрите, может будет толк.

А как это сделать? я вообще нуб.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.