From 889c80eb833c3478b88e0e507196f5a19e706913 Mon Sep 17 00:00:00 2001 From: Rohit Consul Date: Thu, 10 Sep 2015 16:45:01 -0700 Subject: [PATCH] v_tpg: Add example design software v_tpg IP has a new example design available in vivado catalogue. Associated example software is added to the driver along with the xsct script to create sdk project Signed-off-by: Rohit Consul Acked-by: Andrei-Liviu Simion --- .../drivers/v_tpg/examples/main.c | 316 ++++++++++++++++++ .../drivers/v_tpg/examples/readme.txt | 30 ++ .../drivers/v_tpg/examples/vtpg_example.tcl | 35 ++ 3 files changed, 381 insertions(+) create mode 100644 XilinxProcessorIPLib/drivers/v_tpg/examples/main.c create mode 100644 XilinxProcessorIPLib/drivers/v_tpg/examples/readme.txt create mode 100644 XilinxProcessorIPLib/drivers/v_tpg/examples/vtpg_example.tcl diff --git a/XilinxProcessorIPLib/drivers/v_tpg/examples/main.c b/XilinxProcessorIPLib/drivers/v_tpg/examples/main.c new file mode 100644 index 00000000..9b7e8111 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_tpg/examples/main.c @@ -0,0 +1,316 @@ +/******************************************************************************* + * + * Copyright (C) 2015 Xilinx, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Use of the Software is limited solely to applications: + * (a) running on a Xilinx device, or + * (b) that interact with a Xilinx device through a bus or interconnect. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the Xilinx shall not be used + * in advertising or otherwise to promote the sale, use or other dealings in + * this Software without prior written authorization from Xilinx. + * +*******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file main.c +* +* This file demonstrates the example usage of TPG IP available in catalogue +* Please refer v_tpg example design guide for details on HW setup +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00  vyc   09/11/15   Initial Release
+
+* 
+* +******************************************************************************/ + +#include "xparameters.h" +#include "microblaze_sleep.h" +#include "xv_tpg.h" +#include "xvtc.h" +#include "xvidc.h" + +XV_tpg_Config *tpg_Config; +XV_tpg tpg; + +XV_tpg_Config *tpg1_Config; +XV_tpg tpg1; + +XVtc vtc; +XVtc_Config *vtc_Config; +XVtc_Timing vtc_timing; + +u32 volatile *gpio_hlsIpReset; +u32 volatile *gpio_videoLockMonitor; + +#define VideoClockGen_WriteReg(RegOffset, Data) \ + Xil_Out32((XPAR_VIDEO_CLK_BASEADDR) + (RegOffset), (u32)(Data)) +#define VideoClockGen_ReadReg(RegOffset) \ + Xil_In32((XPAR_VIDEO_CLK_BASEADDR) + (RegOffset)) + +int driverInit() +{ + int status; + + vtc_Config = XVtc_LookupConfig(XPAR_V_TC_0_DEVICE_ID); + if(vtc_Config == NULL) + { + xil_printf("ERR:: VTC device not found\r\n"); + return(XST_DEVICE_NOT_FOUND); + } + status = XVtc_CfgInitialize(&vtc, vtc_Config, vtc_Config->BaseAddress); + if(status != XST_SUCCESS) + { + xil_printf("ERR:: VTC Initialization failed %d\r\n", status); + return(XST_FAILURE); + } + + tpg_Config = XV_tpg_LookupConfig(XPAR_V_TPG_0_DEVICE_ID); + if(tpg_Config == NULL) + { + xil_printf("ERR:: TPG device not found\r\n"); + return(XST_DEVICE_NOT_FOUND); + } + status = XV_tpg_CfgInitialize(&tpg, tpg_Config, tpg_Config->BaseAddress); + if(status != XST_SUCCESS) + { + xil_printf("ERR:: TPG Initialization failed %d\r\n", status); + return(XST_FAILURE); + } + + tpg1_Config = XV_tpg_LookupConfig(XPAR_V_TPG_1_DEVICE_ID); + if(tpg1_Config == NULL) + { + xil_printf("ERR:: TPG device not found\r\n"); + return(XST_DEVICE_NOT_FOUND); + } + status = XV_tpg_CfgInitialize(&tpg1, tpg1_Config, tpg1_Config->BaseAddress); + if(status != XST_SUCCESS) + { + xil_printf("ERR:: TPG Initialization failed %d\r\n", status); + return(XST_FAILURE); + } + + return(XST_SUCCESS); +} + +void videoIpConfig(XVidC_VideoMode videoMode) +{ + XVidC_VideoTiming const *timing = XVidC_GetTimingInfo(videoMode); + + XV_tpg_Set_height(&tpg, timing->VActive); + XV_tpg_Set_width(&tpg, timing->HActive); + XV_tpg_Set_colorFormat(&tpg, 0); + XV_tpg_Set_bckgndId(&tpg, XTPG_BKGND_COLOR_BARS); + XV_tpg_Set_ovrlayId(&tpg, 0); + XV_tpg_WriteReg(tpg_Config->BaseAddress, XV_TPG_CTRL_ADDR_AP_CTRL, 0x81); + + XV_tpg_Set_height(&tpg1, timing->VActive); + XV_tpg_Set_width(&tpg1, timing->HActive); + XV_tpg_Set_colorFormat(&tpg1, 0); + XV_tpg_Set_bckgndId(&tpg1, XTPG_BKGND_COLOR_BARS); + XV_tpg_Set_ovrlayId(&tpg1, 0); + XV_tpg_Set_enableInput(&tpg1, 1); + XV_tpg_Set_passthruStartX(&tpg1, 0); + XV_tpg_Set_passthruStartY(&tpg1, 0); + XV_tpg_Set_passthruEndX(&tpg1, timing->HActive); + XV_tpg_Set_passthruEndY(&tpg1, timing->VActive); + XV_tpg_WriteReg(tpg1_Config->BaseAddress, XV_TPG_CTRL_ADDR_AP_CTRL, 0x81); + + vtc_timing.HActiveVideo = timing->HActive/2; + vtc_timing.HFrontPorch = timing->HFrontPorch/2; + vtc_timing.HSyncWidth = timing->HSyncWidth/2; + vtc_timing.HBackPorch = timing->HBackPorch/2; + vtc_timing.HSyncPolarity = timing->HSyncPolarity; + vtc_timing.VActiveVideo = timing->VActive; + vtc_timing.V0FrontPorch = timing->F0PVFrontPorch; + vtc_timing.V0SyncWidth = timing->F0PVSyncWidth; + vtc_timing.V0BackPorch = timing->F0PVBackPorch; + vtc_timing.VSyncPolarity = timing->VSyncPolarity; + XVtc_SetGeneratorTiming(&vtc, &vtc_timing); + XVtc_Enable(&vtc); + XVtc_EnableGenerator(&vtc); + XVtc_RegUpdateEnable(&vtc); +} + +int videoClockConfig(XVidC_VideoMode videoMode) +{ + u32 DIVCLK_DIVIDE = 4; + u32 CLKFBOUT_MULT = 37; + u32 CLKFBOUT_FRAC = 125; + u32 CLKOUT0_DIVIDE; + u32 CLKOUT0_FRAC; + u32 clock_config_reg_0; + u32 clock_config_reg_2; + u32 timeout; + u32 lock; + + + if(videoMode == XVIDC_VM_1080_60_P) + { + CLKOUT0_FRAC = 500; + CLKOUT0_DIVIDE = 12; + } + else if(videoMode == XVIDC_VM_UHD_30_P) + { + CLKOUT0_FRAC = 250; + CLKOUT0_DIVIDE = 6; + } + else if(videoMode == XVIDC_VM_UHD_60_P) + { + CLKOUT0_FRAC = 125; + CLKOUT0_DIVIDE = 3; + } + else + { + print("ERR:: Invalid video mode\r\n"); + return(XST_FAILURE); + } + + clock_config_reg_0 = (1<<26) | (CLKFBOUT_FRAC<<16) | (CLKFBOUT_MULT<<8) | DIVCLK_DIVIDE; + clock_config_reg_2 = (1<<18) | (CLKOUT0_FRAC<<8) | CLKOUT0_DIVIDE; + + VideoClockGen_WriteReg(0x200, clock_config_reg_0); + VideoClockGen_WriteReg(0x208, clock_config_reg_2); + + MB_Sleep(100); + + lock = VideoClockGen_ReadReg(0x4) & 0x1; + if(!lock) //check for lock + { + //Video Clock Generator not locked + VideoClockGen_WriteReg(0x25C, 0x7); + VideoClockGen_WriteReg(0x25C, 0x2); + timeout = 100000; + while(!lock) + { + lock = VideoClockGen_ReadReg(0x4) & 0x1; + --timeout; + if(!timeout) + { + print("ERR:: Video Clock Generator failed lock\r\n"); + return(XST_FAILURE); + } + } + } + print("Video Clock Generator locked\r\n"); + + return(XST_SUCCESS); + +} + +void resetIp(void) +{ + *gpio_hlsIpReset = 0; //reset IPs + + MB_Sleep(100); + + *gpio_hlsIpReset = 1; // release reset + + MB_Sleep(100); + +} + +int main() +{ + int status; + + print("Start test\r\n"); + + gpio_hlsIpReset = (u32*)XPAR_HLS_IP_RESET_BASEADDR; + gpio_videoLockMonitor = (u32*)XPAR_VIDEO_LOCK_MONITOR_BASEADDR; + + status = driverInit(); + if(status != XST_SUCCESS) + { + return(XST_FAILURE); + } + + resetIp(); + + if(*gpio_videoLockMonitor) + { + print("ERR:: Video should not be locked\r\n"); + return(XST_FAILURE); + } + + + videoClockConfig(XVIDC_VM_1080_60_P); + videoIpConfig(XVIDC_VM_1080_60_P); + + MB_Sleep(100); + + if(!gpio_videoLockMonitor) + { + print("ERR:: Video Lock failed for 1080P60\r\n"); + return(XST_FAILURE); + } + else + { + print("1080P60 passed\r\n"); + } + + resetIp(); + + videoClockConfig(XVIDC_VM_UHD_30_P); + videoIpConfig(XVIDC_VM_UHD_30_P); + + MB_Sleep(100); + + if(!gpio_videoLockMonitor) + { + print("ERR:: Video Lock failed for 4KP30\r\n"); + return(XST_FAILURE); + } + else + { + print("4KP30 passed\r\n"); + } + + resetIp(); + + videoClockConfig(XVIDC_VM_UHD_60_P); + videoIpConfig(XVIDC_VM_UHD_60_P); + + MB_Sleep(100); + + if(!gpio_videoLockMonitor) + { + print("ERR:: Video Lock failed for 4KP60\r\n"); + return(XST_FAILURE); + } + else + { + print("4KP60 passed\r\n"); + } + + print("TEST PASS\r\n"); + + + + return 0; +} diff --git a/XilinxProcessorIPLib/drivers/v_tpg/examples/readme.txt b/XilinxProcessorIPLib/drivers/v_tpg/examples/readme.txt new file mode 100644 index 00000000..d3a57fd9 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_tpg/examples/readme.txt @@ -0,0 +1,30 @@ +vtpg_example.tcl automates the process of generating the downloadable bit & elf files from the provided example hdf file. + +Example application design source files (contained within "examples" folder) are tightly coupled with the v_tpg example design available in Vivado Catalogue. +To run the provided tcl + 1. Copy the exported example design hdf file in the "examples" directory of the driver + 2. Launch the xsct terminal + 3. cd into the examples directory + 4. source the tcl file + xsct%>source vtpg_example.tcl + 4. execute the script + xsct%>vtpg_example + +Script will perform following operations + 1. Create workspace + 2. Create HW project + 3. Create BSP + 4. Create Application Project + 5. Build BSP and Application Project + +After the process is complete required files will be available in + bit file -> vtpg_example.sdk/vtpg_example_hw_platform folder + elf file -> vtpg_example.sdk/vtpg_example_design/{Debug/Release} folder + +When executed on the board the example application will perform following operations + 1. Program Video Clock Generator to 1080p@60Hz + 2. Program TPG0 & TPG1 to 1080p@60Hz + 3. Check for Video Lock and report the status (PASS/FAIL)on UART + 4. Repeat Steps 1-3 for 4KP@30Hz and 4KP@60Hz + +Note: Serial terminal baud rate should be set to 9600 diff --git a/XilinxProcessorIPLib/drivers/v_tpg/examples/vtpg_example.tcl b/XilinxProcessorIPLib/drivers/v_tpg/examples/vtpg_example.tcl new file mode 100644 index 00000000..29bc0873 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_tpg/examples/vtpg_example.tcl @@ -0,0 +1,35 @@ +proc vtpg_example args { + + if {[llength $args] != 1} { + puts "error: hdf file name missing from command line" + puts "Please specify hdf to process" + puts "Example Usage: vtpg_example.tcl design1.hdf" + } else { + + set hdf [lindex $args 0] + + #set workspace + puts "Create Workspace" + sdk set_workspace vtpg_example.sdk + + #create hw project + puts "Create HW Project" + sdk create_hw_project -name vtpg_example_hw_platform -hwspec ./$hdf + + #create bsp + puts "Create BSP" + sdk create_bsp_project -name vtpg_example_bsp -hwproject vtpg_example_hw_platform -proc microblaze_0 -os standalone + + #create application project + puts "Create Application Project" + sdk create_app_project -name vtpg_example_design -hwproject vtpg_example_hw_platform -proc microblaze_0 -os standalone -lang C -app {Empty Application} -bsp vtpg_example_bsp + + #copy example source files tp app project + puts "Get Example Design Source Files" + file copy main.c ./vtpg_example.sdk/vtpg_example_design/src + + #build project + puts "Build Project" + sdk build_project -type all + } +}