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

Доброго времени суток, Уважаемые форумчане!

Помогите разобраться с некоторыми вопросами:

1. Нужно ли настраивать (инициализировать) ядро Video In To AXI4-Stream или оно само передает информацию без предварительных настроек.

2. Как лучше (основной критерий простота, наверное) инициализировать VDMA (при помощи описанной Programming Sequence в документации или брать код в examples API-функций)

3. Я пробовал вставить примеры, а именно функцию

int run_triple_frame_buffer(XAxiVdma* InstancePtr, int DeviceId, int hsize,int vsize, int buf_base_addr, int number_frame_count,int enable_frm_cnt_intr);

для инициализации, но данные в память не идут (смотрю по вкладке Memory в режиме Debug)

инициализация по документации

void InitializeVDMA(){
    u32        RegVal;
    //reset AXI DMA
    RegVal    = 0x04;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, RegVal);
        //wait reset 
    while(RegVal & (1 << 2))
    {
        RegVal    = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x30);
    }
        //Инициализируем AXI DMA
    RegVal    = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x30);
    RegVal    = RegVal | 0x1001;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, RegVal);
    RegVal    = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x30);
        xil_printf("AXI DMA control register value: %x\n\r", RegVal);
    RegVal    = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x34);
        xil_printf("AXI DMA status register value: %x\n\r", RegVal);
        //Set start  address
    RegVal    = 0x000000;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, RegVal);
        //Set Frame Delay ???????
    RegVal    = 0x0000000;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, RegVal);
        //Set Horizontal Size 640
    RegVal    = 0x280;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, RegVal);
        //Set Vertical Size 480
    RegVal    = 0x1e0;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, RegVal);
}

Документацию читал, но пока плохо её понимаю.

Буду рад пояснениям, ссылкам, направлениям на цель

Пример инициализации и работы брал из Adam Taylor's chronicles(part 119)

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

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


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

Если еще актуально

1) не нужно, главное правильно для вашей камеры определить настройки ядра, и подключить сигналы шины vid_io_in согласно документации на это ядро и документации на камеру. Также не забыть притянуть сигналы vid_io_in_ce, aclken, axis_enable к "1".

2) я напрямую с регистрами работал:

    //Сбрасываем ядро AXI VDMA
    RegVal    = 0x04;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, RegVal);
    RegVal    = 0;
    //Дожидаемся окончания сброса ядра
    while(RegVal & (1 << 2))
    {
        RegVal    = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x30);
    }
    //Сбрасываем флаг прерывания
    RegVal            = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x34);
    RegVal            = RegVal | 0x1000;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x34, RegVal);

    //Инициализируем AXI VDMA
    RegVal    = Xil_In32(XPAR_AXI_VDMA_3_BASEADDR + 0x30);
    RegVal    = RegVal | 0x108B;
    Xil_Out32(XPAR_AXI_VDMA_3_BASEADDR + 0x30, RegVal);

    // VDMA Interrupt Init
    status = XScuGic_Connect(IntrC, XPAR_FABRIC_AXI_VDMA_0_S2MM_INTROUT_INTR, (Xil_InterruptHandler)DMA_TransferEnd_Handler, NULL);
    if (status != XST_SUCCESS)
    {
        return XST_FAILURE;
    }
    XScuGic_SetPriorityTriggerType(IntrC, XPAR_FABRIC_AXI_VDMA_0_S2MM_INTROUT_INTR, 0, 3);
    XScuGic_Enable(IntrC, XPAR_FABRIC_AXI_VDMA_0_S2MM_INTROUT_INTR);

        //адрес первого кадра
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, ptrBufFrame);
        //адрес второго кадра
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC+4, ptrBufFrame+752*480);
        //адрес третьего кадра
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC+8, ptrBufFrame+2*752*480);
        //параметры кадра
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, 752);
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 752);
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 480);

#define BUF_NUMBER_FRAME   3
uint8_t ptrBufFrame[752*480*BUF_NUMBER_FRAME]__attribute__((aligned(32)));
void DMA_TransferEnd_Handler(void)
{
    u32        RegValue;
    //Сбрасываем флаг прерывания
    RegValue            = Xil_In32(XPAR_AXI_VDMA_0_BASEADDR + 0x34);
    RegValue            = RegValue | 0x1000;
    Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x34, RegValue);

       Xil_DCacheFlushRange(((uint32_t)ptrBufFrame + cntFrame*360960), 752*480);
       cntFrame = (cntFrame + 1)%BUF_NUMBER_FRAME;
       //делаем с кадром что-то
    cntIntrDMA++;

}

3) попробуйте в Vivado вставить debug ядро и посмотреть что есть на шинах данных между Video In To AXI4-Stream и VDMA.

Похожую тему можно посмотреть тут:

https://electronix.ru/forum/index.php?showtopic=144296

Но не знаю как делают люди, но у меня проблема с доступом к памяти кадра, так как после получения свежего кадра, процессор читая память на самом деле прочитает данные из кэша, в котором будет мусор либо старые данные, чтобы освежить кэш, нужно использовать функции Xil_DCacheFlushRange либо Xil_DCacheInvalidateRange. В чем разница кстати не понял. однако это занимает время, поэтому свежий кадр можно получить спустя некоторое время (у меня для области 360960 байт - 11 мс). Либо использовать массив для записи в некешируемой области памяти, но тогда с частым обращением к массиву могут быть ощутимы задержки.

Короче я так и не понял как решить вопрос с кешем и DMA, как правильно с ними работать, может знатоки ответят?

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


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

Вообщем если интересно, то проблема с чтением процем памяти, куда кладется инфа с DMA уже давно известна. Тут предлагается несколько путей решения:

1) отключить кэш полностью, тогда будут проблемы с быстродействием всей программы

2) пометить область памяти, куда кладется буфер кадров - некешируемым, тогда пострадает только быстродействие доступа к этому кадру

3) вручную очищать кэш при поступлении новых данных от DMA, перед чтением. (Тут лучше вместо VDMA юзать DMA, тогда при поступлении новой строки, очищаем кеш именно этой строки и таким образом когда последняя строчка будет получена - весь кадр будет закешериван с минимальной задержкой. Однако возрастает нагрузка на проц, так как придется обрабатывать каждую новую строку кадра. Либо юзать VDMA - тогда при получении всего кадра нужно ждать продолжительное время пока не обновится кэш всего кадра )

4) Использовать ACP порт, вместо HP. Тогда кэш будет обновляться сам. Но тут надо смотреть за требуемой скоростью передачи, так как ACP медленyее чем HP.

Вот ссылка на форум:

форум

форум2

а также тесты по скорости HP и ACP портов в прикрепленном файле (взял с того же форума, не помню ссылку)

acp_faster_then_hp.pdf

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


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

2 ilyaprok

Да, все еще актуально. ,

Спасибо большое за информацию!!!

Вашу тему я читал, но как-то там не понял что и как.

Буду пробовать. Еще раз спасибо!

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


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

Доброго дня!

Подскажите пожалуйста, правильно ли я понял.

 

12121.png

После того как я задал значение VSIZE начинается передача, при условии правильной инициализации и подачи всех сигналов?

И как понять легло ли в память, во вкладке memory я смотрю что лежит по адресам - а там какая-то ерунда.

 

А вот с ila я пока воюю, не могу нормально наловчиться с ним работать, получается через раз. Может кто-нибудь скинь ссыль, как с ним, ila, работать.

Буду признателен за помощь.

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


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

После того как я задал значение VSIZE начинается передача, при условии правильной инициализации и подачи всех сигналов?

Да правильно

И как понять легло ли в память, во вкладке memory я смотрю что лежит по адресам - а там какая-то ерунда.

Вы завели прерывание от VDMA? Еще нужно очистить кеш по адресу принятого кадра и подождать милисекунд 100, чтобы наверняка, дальше можно читать память как вы делали.

А вообще для начала надо понять - приходит ли вообще что-нибудь в VDMA, дальше смотреть, работает ли сам VDMA, а потом только смотреть в память. То есть проследить всю цепочку от источника до пункта назначения.

Как я делал:

У меня были проблемы на хардварном уровне, на параллельном интерфейсе камеры - сигнал PIXCLK имел резкие фронты, которые порождали высокие гармоники, из-за чего было воспринято большее кол-во фронтов, чем ожидалось. (лечилось индуктивностью на этом сигнале, зарезались высокие гармоники), то есть желательно смотреть осциллографом все сигналы с камеры. Не должно быть сильно заваленных фронтов или сильных колебаний на фронтах.

Дальше в Vivado посмотреть с ila сигналы приходящие в само ядро Video In To AXI4-Stream, проверить соответсвуют ли сигналы документам на камеру (длительности, кол-во тактов), желательно проследить несколько раз,в разных местах кадра. Если на этом этапе все хорошо, значит первое звено цепочки можно вычеркивать.

Проверить как подключены сигналы из камеры к ядру, мне пришлось лепить несколько логических функция (И, НЕ) для сигналов active video и hblank, vblank, так как камера выдавала инвертированные сигналы.

Дальше посмотреть какой Stream генерит ядро, тоже с помощью ila, сигналы TLAST, TUSER, TVALID, TREADY.

Дальше посмотреть что генерит VDMA, там достаточно наличие хоть какой то деятельности.

Проверить всю настройки VDMA, софтварную и хардварную.

Проверить прогу, чтобы кеш успевал обновляться.

А вот с ila я пока воюю, не могу нормально наловчиться с ним работать, получается через раз. Может кто-нибудь скинь ссыль, как с ним, ila, работать.

Буду признателен за помощь.

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

Вот мне добрый человек подсказал, из-за этого тоже могут быть проблемы:

https://electronix.ru/forum/index.php?s=&am...t&p=1530631

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


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

У меня были проблемы на хардварном уровне, на параллельном интерфейсе камеры - сигнал PIXCLK имел резкие фронты, которые порождали высокие гармоники, из-за чего было воспринято большее кол-во фронтов, чем ожидалось. (лечилось индуктивностью на этом сигнале, зарезались высокие гармоники), то есть желательно смотреть осциллографом все сигналы с камеры. Не должно быть сильно заваленных фронтов или сильных колебаний на фронтах.

Дальше в Vivado посмотреть с ila сигналы приходящие в само ядро Video In To AXI4-Stream, проверить соответсвуют ли сигналы документам на камеру (длительности, кол-во тактов), желательно проследить несколько раз,в разных местах кадра. Если на этом этапе все хорошо, значит первое звено цепочки можно вычеркивать.

У меня не подключена камера, я имитирую камеру. снизу прикреплю скрин структуры. Возможно , что-то неправильно подключил.

 

По ila спасибо, буду почитать и пробовать. И еще хотел бы спросить по таймингу, убегают времянки, как с этим бороться, какие причины могут быть?

post-99927-1520841863_thumb.png

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

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


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

У меня не подключена камера, я имитирую камеру. снизу прикреплю скрин структуры. Возможно , что-то неправильно подключил.

Тут не подскажу, но возможно для ядра сигнал active_video требуется нисходящие и восходящие фронты для работы внутренней логики, а не просто константное значение.

документ "AXI4-Stream Video IP and System Design Guide" UG934, там прописаны какие сигналы подавать на ядро. для видео - либо hblank vblank, либо vsync hsync. В моем случае были ~hblank ~vblank, поэтому vsync hsync я просто заземлил. Сигнал active_video должен быть в любом случае.

во картинка из того документа (она есть в моей теме)

iOXARrLUTj_vWZzB_zlVpQ.png

 

По ila спасибо, буду почитать и пробовать. И еще хотел бы спросить по таймингу, убегают времянки, как с этим бороться, какие причины могут быть?

Я железо дебажу немного по-другому

вот как тут:

видеоурок

 

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


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

Я смотрел это видео, я только не понял как он работал с XMD console, это он симулировал работу SDK? Напрямую писал и читал из памяти?

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


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

Я смотрел это видео, я только не понял как он работал с XMD console, это он симулировал работу SDK? Напрямую писал и читал из памяти?

Напрямую, в нынешней версии SDK нет XMD консоли, щас там что то другое, не помню абривеатуру (что то типа XSCT). немножко другой синтаксис.

команда чтения памяти и запись в файл выглядит так, как пример (0x01000000 360960 - это адрес и кол-во байт соответственно)

mrd -bin -file "D:/Programming/ZYNQ/logs/mem22.raw" 0x01000000 360960

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


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

Спасибо за ответы.

Я наконец разобрался с ila (по крайней мере, мне удалось увидеть то, что я хотел). Я заметил ошибку и исправил ее, вы были правы, я не выдал там необходимые сигналы.

Теперь информация доходит до vdma. Однако, я хотел бы поинтересоваться

, дальше смотреть, работает ли сам VDMA,
как это проверить, посмотреть данные на выходе S2MM?

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


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

Теперь информация доходит до vdma. Однако, я хотел бы поинтересоваться как это проверить, посмотреть данные на выходе S2MM?

У VDMA все стандартно в плане подключения сигналов, поэтому ошибки могут быть на стороне софта (то есть настройки в регистрах). Сами сигналы приходящие на VDMA желательно проверить, должен быть импульс в начале кадра TUSER, импульсы TLAST - в конце строк, так же TVALID и TREADY согласно документам на AXI-STREAM. Есть еще моменты в настройки самих ядер в Vivado, размеры буферов FIFO, ширина шин и т.д. Их нужно устанавливать исходя из скорости потока камеры и размера кадра, я бы ставил по максимуму буферы первое время, но тут я не уверен, надо поиграться.

Дальше можно просто посмотреть что происходит на S2MM, главное чтобы что то было. Используйте тот код, что я кидал, только адаптируйте под параметры вашего кадра, там ошибка была в

    //Инициализируем AXI VDMA
    RegVal    = Xil_In32(XPAR_AXI_VDMA_3_BASEADDR + 0x30);
    RegVal    = RegVal | 0x108B;
    Xil_Out32(XPAR_AXI_VDMA_3_BASEADDR + 0x30, RegVal);

надо вместо XPAR_AXI_VDMA_3_BASEADDR юзать XPAR_AXI_VDMA_0_BASEADDR.

прочитайте кусок памяти командой чтения из предыдущего сообщения

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


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

надо вместо XPAR_AXI_VDMA_3_BASEADDR юзать XPAR_AXI_VDMA_0_BASEADDR.

прочитайте кусок памяти командой чтения из предыдущего сообщения

Я это сразу поправил, спасибо.

А по сигналам... я сейчас решил посмотреть до конца, как и что формируется Спасибо за информацию.

т.е. после инициализации должна начаться передача данных, правильно я понимаю?

 

Посмотрел. Не формируются на выходе tlast и tuser нету, а tvalid и tready всегда в единице.

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

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


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

Посидел я над документацией ядер, над vivado, ila и прочими штуками.

Понял что ничего не понял. Так как информация, данные, через Video In to AXI4-Stream проходят, а сигналы TLAST и TUSER - нет, почему? Не понимаю!

Вот так выглядит времянка на выходе вышеупомянутого ядра ну и design_1_i/axi_vdma_0_M_AXI_S2MM_WDATA[31:0] затесался

image.png

Вот так сигналы синхронизации заходят в Video In to AXI4-Stream

image.png

Вот так выглядит тестбенч на приблуду, которая иммитирует камеру

image.png

Ну,собственно, проект (сигналы на vblank и hblank поданы тут единожды, в других вариациях они вообще не подключены, разницы я не заметил)

image.png

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

Подскажите пожалуйста как это довести до ума!

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

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


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

Ну,собственно, проект (сигналы на vblank и hblank поданы тут единожды, в других вариациях они вообще не подключены, разницы я не заметил)

вот это место я не понял:

image.png

Вы не можете просто инвертировать сигнал vsync, посмотрите еще раз вот эту диаграмму, которую я приводил ранее:

iOXARrLUTj_vWZzB_zlVpQ.png

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

я это вижу примерно так, может ошибся где, но суть в том, что active video - это не инверсия от vsync, как у вас

image.png

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

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


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

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

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

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

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

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

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

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

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

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