Перейти к содержанию
    

Zynq подключение камеры

Добрый день. Вы уверены, что правильно назначили сигналы на пины? Может ошибка где-то закралась...

Добрый, спасибо за ответ)

Сигналы AVInClk, AVInVS, AVInHS точно правильно назначил на физические ножки. С данными если и будет путанница, то потом разберусь.

Тактовые частоты на сигналы дебаггера не заводят - это плохая практика... У них цепи распространения разные и в Вашем случае синтезатору приходится перекидывать клоковую цепь на сигнальную - от этого и может ругаться.

Посмотрите осциллом - выходит ли тактовая на камеру...

Вот с клоковыми сигналами я не до конца понял. Мою камеру надо тактировать извне от 13-27 МГц. Соответственно этот клок надо вывести из Zynq. Я просто вывел тактовую FCLK1 - 13.333 МГц на физический пин. С этим проблем нет. Осциллографом глянул - такт есть.

Синтезатор ругается на физическую привязку к пину (vid_io_in_clk) сигнала AVInClk, то есть на входной клок от камеры. Я в констрейнах прописал set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets vid_io_in_clk_IBUF]. Он перестал ругаться. Но не притянет ли это дополнительные проблемы?

А как тогда в дебагере посмотреть как данные проходят, если не привязываться к клоковым сигналам?

посмотрите, не нужно ли разрешать работу камеры где-нибудь в ее настройках... Камера скорее всего имеет встроенный PLL - посмотрите, какие настройки ему выставлены.

Начало кадра (в соответствии с AXSI Stream for Video) - один строб на сигнале TUSER. Я работаю с DMA так: процессором сконфигурировал его для приема линии, ядро отдало линию - получаю прерывание от DMA о том, что линия уложена в память, даю команду ждать следующую и т.д. Но тут как кому удобнее. Дело в том, что DMA определяет конец данных по сигналу TLAST - а это (по AXSI Stream for Video) сигнал окончания строки, по этому мне так удобнее.

Камера тактируется извне... Сигналы связанные с AXI Stream Master - будут зависеть от принимающего блока (у меня AXI DMA), я имею ввиду, что пока я не сконфигурирую DMA - он не будет принимать данные, и соответсвенно - шина будет статична? или данные независимо от DMA будут идти вникуда?

Второй вопрос - как мне поймать начало кадра? По сигналу TUSER - но если шина статична - то сигнал TUSER не появится, так ли это? В дебагере в предыдущем посте я вижу именно, что шина не работает, данные статичны.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Синтезатор ругается на физическую привязку к пину (vid_io_in_clk) сигнала AVInClk

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

 

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

Именно так!

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще такая тема с чушью лог.анализатора - там в списке ядер их 2 штуки - system ila и обычные. У меня были глюки с системным. Попробуйте заменить.

Спасибо за помощь)

Я так понял у меня обычные ila. так как нигде не видно приставки system. Но хотелось бы удостоверится, где посмотреть?

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

Второй это ядро по-моему AXI VDMA - с ним не работал, надо курить.

Да я еще слишком неопытен, чтобы писать свое ядро, поэтому использую обычный AXI DMA, возможно возьму AXI VDMA. По идее мне надо просто сложить данные с камеры в DRAM. Но надо как то поймать начало кадра, чтобы первые данные в DRAM были именно с первого пикселя, а не с середины кадра.

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

Сейчас работает на бареметалл, по мере усложнения проекта перейду на FreeRTOS, так как имел с ней опыт на STM32.

Пропускная способность 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 Мбайт/сек.

 

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

 

 

Именно так!

 

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

 

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

Вот спасибо еще раз, вы меня прям сильно выручаете!

Тогда у меня вопрос - как отследить начало кадра?

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

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

И еще вопрос - лучше самому в регистры записывать или использовать готовые функции из BSP?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну тема такая - для бареметал все просто - у вас есть физический адрес буфера в памяти, его можно сделать кольцевым или несколько штук. Дальше передаете этот адрес ядру ДМА, он передает данные, дергает прерывание и вы ему адрес заменяете или он сам показывает адрес последней транзакции.

Если будут пингвины, то нужно маппировать физические адреса на виртуальные и гуглите nmap

НАсчет фриртос не знаю.

Сам делаю похожую задачу))

 

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

Можете отдельно ответвить от шины TUSER и завести его как прерывание. В софтварной части Вы должны распределить память под кадр, в начале работы указываете ДМА первый адрес и длину строки - он положит туда одну строку (не обязательно первую, но это не срашно - см. далее), по прерыванию от ДМА задаете ему новый адрес - смещенный на длину строки первый, опять запускаете его записью длины строки, опять прерывание и т.д.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Можете отдельно ответвить от шины TUSER и завести его как прерывание. В софтварной части Вы должны распределить память под кадр, в начале работы указываете ДМА первый адрес и длину строки - он положит туда одну строку (не обязательно первую, но это не срашно - см. далее), по прерыванию от ДМА задаете ему новый адрес - смещенный на длину строки первый, опять запускаете его записью длины строки, опять прерывание и т.д.

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

Спасибо. Да TUSER завел как прерывание, тоже так хотел сделать. Теперь раз мысли совпали, так и сделаю

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Опять нужна помощь(

Данные c ядра AV2AXISV_0 дальше не идут. DMA не дает сигнал tready. Я так понимаю в этом проблема.

Но почему он не дает сигнал готовности принять?

Читал несколько раз даташит на DMA AXI ядро. Написал в ручную регистры, которые надо заполнять. проверил - заполняются правильно. DMA стартует и останавливается (биты в нужных регистрах устанавливаются и сбрасываются). Но по факту ничего не происходит, в прерывание не заходит. Ни в DMA, ни в TUSER. То есть мое подозрение, что слабое место в связке между AV2AXISV_0 и DMA.

Вот дебаггер:

TOPWKX4qQfWjbjx-4RNlkQ.png

Вот код

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для быстрой проверки: отключите 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;
    }
};

 

Обработка прерывания с запросом очередной порции данных

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обратите внимание на модуль AVInput внутри ядра - там есть константы, они для видеодекодеров, для Вашей камерв могут не подойти.

Обратите внимание на то, как используются и комбинируются входные сигналы.

Будет не понятно - спрашивайте.

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

Y9aKP6UYRsmsmE3BmFlWBg.png

TUSER - вообще странно появляется, не привязан ни к чему.

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

Внутри даташита на MT9V034 есть такая таблица:

oxNQ0zDpSJGp6KJUZ02ziw.png

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

Fi9NBVH-TVyJkkCzdx0K4A.png

Если я перепишу параметры в AVInput, заработает ядро? Или тут надо логику переписывать? Может тогда проще по LVDS линии соединится?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообщем вернулся к первоначальному варианту с VideoIn To AXI4 Stream.

сигналы с камеры завел так:

hblank = ~LINE_VALID

vblank = ~FARME_VALID

active_video = LINE_VALID&FARME_VALID

tready на AXI шине поставил в 1.

Снял датаграммы:

Это то что на входе ядра - сигналы с камеры

9VEhnlf4SNeFkfOcctOtKw.png

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

zVQJJbPRQNW3tsfOqwsjdg.png

Кажется что работает.

Теперь соединил tready к DMA.

Сигналы с камеры по прежнему идут.

А на АКСИ шине ничего нет, сигнал tready из DMA все блокирует.

Изменено пользователем ilyaprok

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

tvalid очень странно себя ведет..

 

Если ДМА блокирует - значит количество принятых данных не совпадает с запрошенным! Посмотрите статус ДМА - там в этом случае должна быть выставлена ошибка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добился того, что 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

AXI VDMA можете не пробовать - не тратьте время....

Разберитесь с сигналами - они явно не в порядке...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

AXI VDMA можете не пробовать - не тратьте время....

Разберитесь с сигналами - они явно не в порядке...

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

 

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

F1CGySlKRr6CPIf1klUHug.png

В SDK при этом DMA совершает 1-11 транзакций по 752 байта, и останавливается по внутренней ошибке.

То что я совершаю транзакции по 752 байта - эта одна линия, это нормально? TUSER вообще никогда не появляется. Изменяя 752 байта в большую сторону, ошибок не возникает, но в лог анализаторе такая же картина.

Изменено пользователем ilyaprok

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я давал Вам свое ядро, что бы Вы могли там сигнальчики посмотреть и если что - обсудить... Вы уверены, что длительность строки у Вас правильная (а не плавает из-за каких-либо факторов)?

Все-таки рекомендую Вам сначала удостовериться, что все сигналы от камеры правильные и Вы четко понимаете их длительности и соотношения!

Нужно было бы добавить счетчик по стробу данных в строке и посмотреть, сколько их реально приходит - не плавает ли... Как соотносятся стробы кадра и строки и т.д.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...