|
|
  |
Zynq подключение камеры, Вопросы новичка |
|
|
|
Nov 15 2017, 08:38
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 29-10-17
Пользователь №: 99 964

|
Цитата(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 не появится, так ли это? В дебагере в предыдущем посте я вижу именно, что шина не работает, данные статичны.
|
|
|
|
|
Nov 15 2017, 08:45
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 8-01-12
Из: Беларусь
Пользователь №: 69 226

|
Цитата Синтезатор ругается на физическую привязку к пину (vid_io_in_clk) сигнала AVInClk Все правильно, значит пин не клоковый... Пока это не страшно. Цитата я имею ввиду, что пока я не сконфигурирую DMA - он не будет принимать данные, и соответсвенно - шина будет статична Именно так! Но Вы можете проанализировать поведение внутренних цепей ядра... Про тактовые на дебагере - не надо их заводить для просмотра как сигнал... Просто знайте, что они есть... Если дебагер показывает времянку - он уже от чего-то тактируется...
|
|
|
|
|
Nov 15 2017, 08:53
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 29-10-17
Пользователь №: 99 964

|
Цитата(_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?
|
|
|
|
|
Nov 15 2017, 09:14
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 8-01-12
Из: Беларусь
Пользователь №: 69 226

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

Группа: Участник
Сообщений: 42
Регистрация: 29-10-17
Пользователь №: 99 964

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

Группа: Участник
Сообщений: 42
Регистрация: 29-10-17
Пользователь №: 99 964

|
Опять нужна помощь( Данные 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); ...
Сообщение отредактировал ilyaprok - Nov 15 2017, 15:42
|
|
|
|
|
Nov 15 2017, 17:29
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 8-01-12
Из: Беларусь
Пользователь №: 69 226

|
Для быстрой проверки: отключите 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; } }; Обработка прерывания с запросом очередной порции данных
|
|
|
|
|
Nov 15 2017, 20:33
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 29-10-17
Пользователь №: 99 964

|
Цитата(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 линии соединится?
|
|
|
|
|
Nov 16 2017, 07:45
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 29-10-17
Пользователь №: 99 964

|
Вообщем вернулся к первоначальному варианту с VideoIn To AXI4 Stream. сигналы с камеры завел так: hblank = ~LINE_VALID vblank = ~FARME_VALID active_video = LINE_VALID&FARME_VALID tready на AXI шине поставил в 1. Снял датаграммы: Это то что на входе ядра - сигналы с камеры  Это то что на выходе ядра на AXI шине  Кажется что работает. Теперь соединил tready к DMA. Сигналы с камеры по прежнему идут. А на АКСИ шине ничего нет, сигнал tready из DMA все блокирует.
Сообщение отредактировал ilyaprok - Nov 16 2017, 08:04
|
|
|
|
|
Nov 16 2017, 09:37
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 29-10-17
Пользователь №: 99 964

|
Добился того, что 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.
|
|
|
|
|
Nov 16 2017, 10:41
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 29-10-17
Пользователь №: 99 964

|
Цитата(svedach @ Nov 16 2017, 15:16)  AXI VDMA можете не пробовать - не тратьте время.... Разберитесь с сигналами - они явно не в порядке... хорошо, спасибо. А что не так с сигналами? Как должно выглядеть? Если запустить лог анализатор в вивадо на по фронту TREADY и при этом запустить прогу в SDK, то пооучается вот это:  В SDK при этом DMA совершает 1-11 транзакций по 752 байта, и останавливается по внутренней ошибке. То что я совершаю транзакции по 752 байта - эта одна линия, это нормально? TUSER вообще никогда не появляется. Изменяя 752 байта в большую сторону, ошибок не возникает, но в лог анализаторе такая же картина.
Сообщение отредактировал ilyaprok - Nov 16 2017, 10:41
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|