当前位置:   article > 正文

Zynq-PS-SDK(15) 之 OV5640-HDMI 视频通路软件配置_ov5640sdk

ov5640sdk

Zynq-PS-SDK(13) 之 VDMA+VTC+AXI4S-VideoOut 视频通路软件配置》将硬件做好后,导出到 SDK,我们进行代码的编写,代码主要分为两部分:

1、SCCB 的 I2C 对 OV5640 进行配置;

2、配置 VDMA + VTC + Dynamic Clock;

reset,完成 SCCB 的配置,然后进行 IP 核的配置,main 函数如下所示:

  1. /************************************************************************/
  2. /* */
  3. /* display_demo.c -- ALINX AX7010 HDMI Display demonstration */
  4. /* */
  5. /************************************************************************/
  6. /* ------------------------------------------------------------ */
  7. /* Include File Definitions */
  8. /* ------------------------------------------------------------ */
  9. #include "display_demo.h"
  10. #include "display_ctrl/display_ctrl.h"
  11. #include <stdio.h>
  12. #include "math.h"
  13. #include <ctype.h>
  14. #include <stdlib.h>
  15. #include "xil_types.h"
  16. #include "xil_cache.h"
  17. #include "xparameters.h"
  18. #include "xiicps.h"
  19. #include "vdma.h"
  20. #include "i2c/PS_i2c.h"
  21. #include "xgpio.h"
  22. #include "sleep.h"
  23. #include "ov5640.h"
  24. #include "steph_vdma.h"
  25. /*
  26. * XPAR redefines
  27. */
  28. #define DYNCLK_BASEADDR XPAR_AXI_DYNCLK_0_BASEADDR
  29. #define VGA_VDMA_ID XPAR_AXIVDMA_0_DEVICE_ID
  30. #define DISP_VTC_ID XPAR_VTC_0_DEVICE_ID
  31. #define VID_VTC_IRPT_ID XPS_FPGA3_INT_ID
  32. #define VID_GPIO_IRPT_ID XPS_FPGA4_INT_ID
  33. #define SCU_TIMER_ID XPAR_SCUTIMER_DEVICE_ID
  34. #define UART_BASEADDR XPAR_PS7_UART_1_BASEADDR
  35. /* ------------------------------------------------------------ */
  36. /* Global Variables */
  37. /* ------------------------------------------------------------ */
  38. /*
  39. * Display Driver structs
  40. */
  41. DisplayCtrl dispCtrl;
  42. XAxiVdma vdma;
  43. XIicPs ps_i2c0;
  44. XGpio cmos_rstn;
  45. /*
  46. * Framebuffers for video data
  47. */
  48. u8 frameBuf[DISPLAY_NUM_FRAMES][DEMO_MAX_FRAME] __attribute__ ((aligned(64)));
  49. u8 *pFrames[DISPLAY_NUM_FRAMES]; //array of pointers to the frame buffers
  50. /* ------------------------------------------------------------ */
  51. /* Procedure Definitions */
  52. /* ------------------------------------------------------------ */
  53. int main(void)
  54. {
  55. int Status;
  56. XAxiVdma_Config *vdmaConfig;
  57. int i;
  58. /*
  59. * Initialize an array of pointers to the 3 frame buffers
  60. */
  61. for (i = 0; i < DISPLAY_NUM_FRAMES; i++)
  62. {
  63. pFrames[i] = frameBuf[i];
  64. memset(pFrames[i], 0, DEMO_MAX_FRAME);
  65. Xil_DCacheFlushRange((INTPTR) pFrames[i], DEMO_MAX_FRAME) ;
  66. }
  67. i2c_init(&ps_i2c0, XPAR_XIICPS_0_DEVICE_ID,40000);
  68. XGpio_Initialize(&cmos_rstn, XPAR_CMOS_RST_DEVICE_ID); //initialize GPIO IP
  69. XGpio_SetDataDirection(&cmos_rstn, 1, 0x0); //set GPIO as output
  70. XGpio_DiscreteWrite(&cmos_rstn, 1, 0x1);
  71. usleep(500000);
  72. XGpio_DiscreteWrite(&cmos_rstn, 1, 0x0); //set GPIO output value to 0
  73. usleep(500000);
  74. XGpio_DiscreteWrite(&cmos_rstn, 1, 0x1);
  75. usleep(500000);
  76. /*
  77. * Initialize Sensor
  78. */
  79. sensor_init(&ps_i2c0);
  80. /*
  81. * Initialize VDMA driver
  82. */
  83. // Reset StephenZhou's IP
  84. Xil_Out32(XPAR_STEPH_OV5640_0_S00_AXI_BASEADDR, 0x00000000);
  85. usleep(500000);
  86. Xil_Out32(XPAR_STEPH_OV5640_0_S00_AXI_BASEADDR, 0x00000001);
  87. vdmaConfig = XAxiVdma_LookupConfig(VGA_VDMA_ID);
  88. if (!vdmaConfig)
  89. {
  90. xil_printf("No video DMA found for ID %d\r\n", VGA_VDMA_ID);
  91. }
  92. Status = XAxiVdma_CfgInitialize(&vdma, vdmaConfig, vdmaConfig->BaseAddress);
  93. if (Status != XST_SUCCESS)
  94. {
  95. xil_printf("VDMA Configuration Initialization failed %d\r\n", Status);
  96. }
  97. /*
  98. * Initialize the Display controller and start it
  99. */
  100. Status = DisplayInitialize(&dispCtrl, &vdma, DISP_VTC_ID, DYNCLK_BASEADDR,pFrames, DEMO_STRIDE);
  101. if (Status != XST_SUCCESS)
  102. {
  103. xil_printf("Display Ctrl initialization failed during demo initialization%d\r\n", Status);
  104. }
  105. Status = DisplayStart(&dispCtrl);
  106. if (Status != XST_SUCCESS)
  107. {
  108. xil_printf("Couldn't start display during demo initialization%d\r\n", Status);
  109. }
  110. /* Clear frame buffer */
  111. memset(dispCtrl.framePtr[dispCtrl.curFrame], 0, 1920 * 1080 * 3);
  112. /* Start Sensor Vdma */
  113. // vdma_write_init(XPAR_AXIVDMA_1_DEVICE_ID,1280 * 3,720,1280 * 3,(unsigned int)dispCtrl.framePtr[dispCtrl.curFrame]);
  114. Steph_VDMAInit(&vdma, VGA_VDMA_ID, 1280, 720, DEMO_STRIDE, (unsigned int) pFrames[0]);
  115. while(1);
  116. return 0;
  117. }

VDMA 的配置,配置了读写通道:

  1. /******************** Include files **********************************/
  2. #include "xaxivdma.h"
  3. #include "xparameters.h"
  4. #include "xil_exception.h"
  5. #define STEPH_VDMA_DBG 1
  6. typedef struct steph_vdma_desc {
  7. /** The XAxiVdma driver instance data. */
  8. XAxiVdma* InstancePtr;
  9. /** The Read channel configure. */
  10. XAxiVdma_DmaSetup ReadCfg;
  11. /** The Write channel configure. */
  12. XAxiVdma_DmaSetup WriteCfg;
  13. /* Horizontal size of frame */
  14. unsigned int hsize;
  15. /* Stride horizontal size of frame */
  16. unsigned int stride;
  17. /* Vertical size of frame */
  18. unsigned int vsize;
  19. /* FrameBuffer address from where read and write will be done by VDMA */
  20. unsigned int fb_addr;
  21. } steph_vdma_desc_t;
  22. steph_vdma_desc_t steph_vdma;
  23. static int _Steph_VDMA_ConfigWriteChannel(steph_vdma_desc_t *steph_vdma)
  24. {
  25. int Status = XST_SUCCESS;
  26. u32 Addr;
  27. steph_vdma->WriteCfg.VertSizeInput = steph_vdma->vsize;
  28. steph_vdma->WriteCfg.HoriSizeInput = steph_vdma->hsize;
  29. steph_vdma->WriteCfg.Stride = steph_vdma->stride;
  30. steph_vdma->WriteCfg.FrameDelay = 0;
  31. // Circular mode
  32. steph_vdma->WriteCfg.EnableCircularBuf = 1;
  33. // GenLock enable
  34. steph_vdma->WriteCfg.EnableSync = 1;
  35. steph_vdma->WriteCfg.PointNum = 0;
  36. steph_vdma->WriteCfg.EnableFrameCounter = 0;
  37. /* We are not doing parking */
  38. steph_vdma->WriteCfg.FixedFrameStoreAddr= 0;
  39. steph_vdma->WriteCfg.GenLockRepeat = 0;
  40. Status = XAxiVdma_DmaConfig(steph_vdma->InstancePtr, XAXIVDMA_WRITE, &steph_vdma->WriteCfg);
  41. if (Status != XST_SUCCESS) {
  42. xil_printf("[ERROR] : Write channel config failed %d\r\n", Status);
  43. return Status;
  44. }
  45. // Configure the framebuffer
  46. Addr = steph_vdma->fb_addr;
  47. for(int Index = 0; Index < steph_vdma->InstancePtr->MaxNumFrames; Index++)
  48. {
  49. steph_vdma->WriteCfg.FrameStoreStartAddr[Index] = Addr;
  50. Addr += (steph_vdma->hsize * steph_vdma->vsize);
  51. }
  52. // Set the framebuffer addresses for transfer in the DMA engine
  53. Status = XAxiVdma_DmaSetBufferAddr(steph_vdma->InstancePtr, XAXIVDMA_WRITE,
  54. steph_vdma->WriteCfg.FrameStoreStartAddr);
  55. if (Status != XST_SUCCESS)
  56. {
  57. xil_printf("[ERROR] : Write channel set buffer address failed %d\r\n", Status);
  58. return Status;
  59. }
  60. return Status;
  61. }
  62. static int _Steph_VDMA_ConfigReadChannel(steph_vdma_desc_t *steph_vdma)
  63. {
  64. int Status = XST_SUCCESS;
  65. u32 Addr;
  66. steph_vdma->ReadCfg.VertSizeInput = steph_vdma->vsize;
  67. steph_vdma->ReadCfg.HoriSizeInput = steph_vdma->hsize;
  68. steph_vdma->ReadCfg.Stride = steph_vdma->stride;
  69. steph_vdma->ReadCfg.FrameDelay = 0;
  70. // Circular mode
  71. steph_vdma->ReadCfg.EnableCircularBuf = 1;
  72. // GenLock enable
  73. steph_vdma->ReadCfg.EnableSync = 1;
  74. steph_vdma->ReadCfg.PointNum = 0;
  75. steph_vdma->ReadCfg.EnableFrameCounter = 0;
  76. /* We are not doing parking */
  77. steph_vdma->ReadCfg.FixedFrameStoreAddr= 0;
  78. steph_vdma->ReadCfg.GenLockRepeat = 0;
  79. Status = XAxiVdma_DmaConfig(steph_vdma->InstancePtr, XAXIVDMA_READ, &steph_vdma->ReadCfg);
  80. if (Status != XST_SUCCESS) {
  81. xil_printf("[ERROR] : Read channel config failed %d\r\n", Status);
  82. return Status;
  83. }
  84. // Configure the framebuffer
  85. Addr = steph_vdma->fb_addr;
  86. for(int Index = 0; Index < steph_vdma->InstancePtr->MaxNumFrames; Index++)
  87. {
  88. steph_vdma->ReadCfg.FrameStoreStartAddr[Index] = Addr;
  89. Addr += (steph_vdma->hsize * steph_vdma->vsize);
  90. }
  91. // Set the framebuffer addresses for transfer in the DMA engine
  92. Status = XAxiVdma_DmaSetBufferAddr(steph_vdma->InstancePtr, XAXIVDMA_READ,
  93. steph_vdma->ReadCfg.FrameStoreStartAddr);
  94. if (Status != XST_SUCCESS)
  95. {
  96. xil_printf("[ERROR] : Read channel set buffer address failed %d\r\n", Status);
  97. return Status;
  98. }
  99. return Status;
  100. }
  101. static int _Steph_VDMA_StartWriteChannel(steph_vdma_desc_t *steph_vdma)
  102. {
  103. int Status = XST_SUCCESS;
  104. Status = XAxiVdma_DmaStart(steph_vdma->InstancePtr, XAXIVDMA_WRITE);
  105. if (Status != XST_SUCCESS)
  106. {
  107. xil_printf("[ERROR] : Start Write transfer failed %d\r\n", Status);
  108. }
  109. return Status;
  110. }
  111. static int _Steph_VDMA_StartReadChannel(steph_vdma_desc_t *steph_vdma)
  112. {
  113. int Status = XST_SUCCESS;
  114. Status = XAxiVdma_DmaStart(steph_vdma->InstancePtr, XAXIVDMA_READ);
  115. if (Status != XST_SUCCESS)
  116. {
  117. xil_printf("[ERROR] : Start Read transfer failed %d\r\n", Status);
  118. }
  119. return Status;
  120. }
  121. int Steph_VDMAInit(XAxiVdma *_InstancePtr, int device_id, int hsize, int vsize, int stride, int fb_addr)
  122. {
  123. int Status = XST_SUCCESS;
  124. XAxiVdma_Config *Config;
  125. Config = XAxiVdma_LookupConfig(device_id);
  126. if (!Config)
  127. {
  128. xil_printf("[ERROR] : No video DMA found for ID %d\r\n",device_id);
  129. return XST_FAILURE;
  130. }
  131. /* Initialize DMA engine */
  132. Status = XAxiVdma_CfgInitialize(_InstancePtr, Config, Config->BaseAddress);
  133. if (Status != XST_SUCCESS)
  134. {
  135. xil_printf("[ERROR] : Configuration Initialization failed %d\r\n",Status);
  136. return Status;
  137. }
  138. steph_vdma.InstancePtr = _InstancePtr;
  139. steph_vdma.hsize = hsize * (Config->Mm2SStreamWidth>>3);
  140. steph_vdma.stride = stride;
  141. steph_vdma.vsize = vsize;
  142. steph_vdma.fb_addr = fb_addr;
  143. #ifdef STEPH_VDMA_DBG
  144. xil_printf("hsize = %d\r\n",hsize);
  145. xil_printf("stride = %d\r\n",steph_vdma.stride);
  146. xil_printf("vsize = %d\r\n",vsize);
  147. xil_printf("fb_addr = 0x%08X\r\n",fb_addr);
  148. #endif
  149. // Configure the write channel
  150. Status = _Steph_VDMA_ConfigWriteChannel(&steph_vdma);
  151. if (Status != XST_SUCCESS)
  152. {
  153. xil_printf("[ERROR] : Write channel setup failed %d\r\n", Status);
  154. return Status;
  155. }
  156. // Configure the read channel
  157. Status = _Steph_VDMA_ConfigReadChannel(&steph_vdma);
  158. if (Status != XST_SUCCESS)
  159. {
  160. xil_printf("[ERROR] : Read channel setup failed %d\r\n", Status);
  161. return Status;
  162. }
  163. // Start the write channel
  164. Status = _Steph_VDMA_StartWriteChannel(&steph_vdma);
  165. if (Status != XST_SUCCESS)
  166. {
  167. xil_printf("[ERROR] : Start Write channel failed %d\r\n", Status);
  168. return Status;
  169. }
  170. // Configure the read channel
  171. Status = _Steph_VDMA_StartReadChannel(&steph_vdma);
  172. if (Status != XST_SUCCESS)
  173. {
  174. xil_printf("[ERROR] : Start Read channel failed %d\r\n", Status);
  175. return Status;
  176. }
  177. xil_printf("StephenZhou VDMA OK...\r\n");
  178. return Status;
  179. }

3 块 framebuffer 轮流使用,开启 GenLock;

更多寄存器的配置详细,参考 pg020;主要是配置一些宽,高,framebuffer 地址,GenLock 同步方式等;

 

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/881532
推荐阅读
相关标签
  

闽ICP备14008679号