/** * * Main function * * This function is the main entry point of the example on DMA core. It sets up * DMA engine to be ready to receive and send frames, and start the transfers. * It waits for the transfer of the specified number of frame sets, and check * for transfer errors. * * @return * - XST_SUCCESS if example finishes successfully * - XST_FAILURE if example fails. * * @note None. * ******************************************************************************/ int vdma_setup(XIntc controller) { Intc = controller; int Status; XAxiVdma_Config *Config; XAxiVdma_FrameCounter FrameCfg; WriteDone = 0; ReadDone = 0; WriteError = 0; ReadError = 0; ReadFrameAddr = READ_ADDRESS_BASE; WriteFrameAddr = WRITE_ADDRESS_BASE; xil_printf("\r\n--- Entering vdma_setup() --- \r\n"); /* The information of the XAxiVdma_Config comes from hardware build. * The user IP should pass this information to the AXI DMA core. */ Config = XAxiVdma_LookupConfig(DMA_DEVICE_ID); if (!Config) { xil_printf( "No video DMA found for ID %d\r\n", DMA_DEVICE_ID); return XST_FAILURE; } /* Initialize DMA engine */ Status = XAxiVdma_CfgInitialize(&AxiVdma, Config, Config->BaseAddress); if (Status != XST_SUCCESS) { xil_printf( "Configuration Initialization failed %d\r\n", Status); return XST_FAILURE; } Status = XAxiVdma_SetFrmStore(&AxiVdma, NUMBER_OF_READ_FRAMES, XAXIVDMA_READ); if (Status != XST_SUCCESS) { xil_printf( "Setting Frame Store Number Failed in Read Channel" " %d\r\n", Status); return XST_FAILURE; } Status = XAxiVdma_SetFrmStore(&AxiVdma, NUMBER_OF_WRITE_FRAMES, XAXIVDMA_WRITE); if (Status != XST_SUCCESS) { xil_printf( "Setting Frame Store Number Failed in Write Channel" " %d\r\n", Status); return XST_FAILURE; } /* Setup frame counter and delay counter for both channels * * This is to monitor the progress of the test only * * WARNING: In free-run mode, interrupts may overwhelm the system. * In that case, it is better to disable interrupts. */ FrameCfg.ReadFrameCount = NUMBER_OF_READ_FRAMES; FrameCfg.WriteFrameCount = NUMBER_OF_WRITE_FRAMES; FrameCfg.ReadDelayTimerCount = DELAY_TIMER_COUNTER; FrameCfg.WriteDelayTimerCount = DELAY_TIMER_COUNTER; Status = XAxiVdma_SetFrameCounter(&AxiVdma, &FrameCfg); if (Status != XST_SUCCESS) { xil_printf( "Set frame counter failed %d\r\n", Status); if(Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); return XST_FAILURE; } /* * Setup your video IP that writes to the memory */ /* Setup the write channel */ Status = WriteSetup(&AxiVdma); if (Status != XST_SUCCESS) { xil_printf( "Write channel setup failed %d\r\n", Status); if(Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); return XST_FAILURE; } /* * Setup your video IP that reads from the memory */ /* Setup the read channel */ Status = ReadSetup(&AxiVdma); if (Status != XST_SUCCESS) { xil_printf( "Read channel setup failed %d\r\n", Status); if(Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); return XST_FAILURE; } Status = SetupIntrSystem(&AxiVdma, READ_INTR_ID, WRITE_INTR_ID); if (Status != XST_SUCCESS) { xil_printf( "Setup interrupt system failed %d\r\n", Status); return XST_FAILURE; } /* Register callback functions */ // XAxiVdma_SetCallBack(&AxiVdma, XAXIVDMA_HANDLER_GENERAL, ReadCallBack, // (void *)&AxiVdma, XAXIVDMA_READ); // // XAxiVdma_SetCallBack(&AxiVdma, XAXIVDMA_HANDLER_ERROR, // ReadErrorCallBack, (void *)&AxiVdma, XAXIVDMA_READ); XAxiVdma_SetCallBack(&AxiVdma, XAXIVDMA_HANDLER_GENERAL, WriteCallBack, (void *)&AxiVdma, XAXIVDMA_WRITE); XAxiVdma_SetCallBack(&AxiVdma, XAXIVDMA_HANDLER_ERROR, WriteErrorCallBack, (void *)&AxiVdma, XAXIVDMA_WRITE); /* Enable your video IP interrupts if needed */ /* Start the DMA engine to transfer */ Status = StartTransfer(&AxiVdma); if (Status != XST_SUCCESS) { if(Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); return XST_FAILURE; } /* Enable DMA read and write channel interrupts * * If interrupts overwhelms the system, please do not enable interrupt */ // XAxiVdma_IntrEnable(&AxiVdma, XAXIVDMA_IXR_FRMCNT_MASK, XAXIVDMA_WRITE); // XAxiVdma_IntrEnable(&AxiVdma, XAXIVDMA_IXR_FRMCNT_MASK, XAXIVDMA_READ); /* Every set of frame buffer finish causes a completion interrupt */ // while ((WriteDone < NUM_TEST_FRAME_SETS) && !ReadError && // (ReadDone < NUM_TEST_FRAME_SETS) && !WriteError) { // /* NOP */ // } // if (ReadError || WriteError) { // xil_printf("Test has transfer error %d/%d\r\n", // ReadError, WriteError); // // Status = XST_FAILURE; // } // else { // xil_printf("Test passed\r\n"); // } xil_printf("\r\n--- Exiting vdma_setup() --- \r\n"); // DisableIntrSystem(READ_INTR_ID, WRITE_INTR_ID); if (Status != XST_SUCCESS) { if(Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); return XST_FAILURE; } return XST_SUCCESS; }
void initVideo() { init_platform(); // Necessary for all programs. int Status; // Keep track of success/failure of system function calls. // There are 3 steps to initializing the vdma driver and IP. // Step 1: lookup the memory structure that is used to access the vdma driver. XAxiVdma_Config * VideoDMAConfig = XAxiVdma_LookupConfig( XPAR_AXI_VDMA_0_DEVICE_ID); // Step 2: Initialize the memory structure and the hardware. if (XST_FAILURE == XAxiVdma_CfgInitialize(&videoDMAController, VideoDMAConfig, XPAR_AXI_VDMA_0_BASEADDR)) { xil_printf("VideoDMA Did not initialize.\r\n"); } // Step 3: (optional) set the frame store number. if (XST_FAILURE == XAxiVdma_SetFrmStore(&videoDMAController, 2, XAXIVDMA_READ)) { xil_printf("Set Frame Store Failed."); } // Initialization is complete at this point. // Setup the frame counter. We want two read frames. We don't need any write frames but the // function generates an error if you set the write frame count to 0. We set it to 2 // but ignore it because we don't need a write channel at all. XAxiVdma_FrameCounter myFrameConfig; myFrameConfig.ReadFrameCount = 2; myFrameConfig.ReadDelayTimerCount = 10; myFrameConfig.WriteFrameCount = 2; myFrameConfig.WriteDelayTimerCount = 10; Status = XAxiVdma_SetFrameCounter(&videoDMAController, &myFrameConfig); if (Status != XST_SUCCESS) { xil_printf("Set frame counter failed %d\r\n", Status); if (Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); } // Now we tell the driver about the geometry of our frame buffer and a few other things. // Our image is 480 x 640. XAxiVdma_DmaSetup myFrameBuffer; myFrameBuffer.VertSizeInput = 480; // 480 vertical pixels. myFrameBuffer.HoriSizeInput = 640 * 4; // 640 horizontal (32-bit pixels). myFrameBuffer.Stride = 640 * 4; // Dont' worry about the rest of the values. myFrameBuffer.FrameDelay = 0; myFrameBuffer.EnableCircularBuf = 1; myFrameBuffer.EnableSync = 0; myFrameBuffer.PointNum = 0; myFrameBuffer.EnableFrameCounter = 0; myFrameBuffer.FixedFrameStoreAddr = 0; if (XST_FAILURE == XAxiVdma_DmaConfig(&videoDMAController, XAXIVDMA_READ, &myFrameBuffer)) { xil_printf("DMA Config Failed\r\n"); } // We need to give the frame buffer pointers to the memory that it will use. This memory // is where you will write your video data. The vdma IP/driver then streams it to the HDMI // IP. myFrameBuffer.FrameStoreStartAddr[0] = FRAME_BUFFER_ADDR; myFrameBuffer.FrameStoreStartAddr[1] = FRAME_BUFFER_ADDR + 4*640*480; if (XST_FAILURE == XAxiVdma_DmaSetBufferAddr(&videoDMAController, XAXIVDMA_READ, myFrameBuffer.FrameStoreStartAddr)) { xil_printf("DMA Set Address Failed Failed\r\n"); } // Print a sanity message if you get this far. xil_printf("Woohoo! I made it through initialization.\n\r"); // Now, let's get ready to start displaying some stuff on the screen. // The variables framePointer and framePointer1 are just pointers to the base address // of frame 0 and frame 1. // This tells the HDMI controller the resolution of your display (there must be a better way to do this). XIo_Out32(XPAR_AXI_HDMI_0_BASEADDR, 640*480); // Start the DMA for the read channel only. if (XST_FAILURE == XAxiVdma_DmaStart(&videoDMAController, XAXIVDMA_READ)) { xil_printf("DMA START FAILED\r\n"); } // We have two frames, let's park on frame 0. Use frameIndex to index them. // Note that you have to start the DMA process before parking on a frame. if (XST_FAILURE == XAxiVdma_StartParking(&videoDMAController, frameIndex, XAXIVDMA_READ)) { xil_printf("vdma parking failed\n\r"); } }