Если еще актуально
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, как правильно с ними работать, может знатоки ответят?