diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/data/v_hscaler.mdd b/XilinxProcessorIPLib/drivers/v_hscaler/data/v_hscaler.mdd new file mode 100644 index 00000000..9e4ca456 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/data/v_hscaler.mdd @@ -0,0 +1,18 @@ +# ============================================================== +# File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC +# Version: 2015.1 +# Copyright (C) 2015 Xilinx Inc. All rights reserved. +# +# ============================================================== + +OPTION psf_version = 2.1; + +BEGIN driver v_hscaler + + OPTION supported_peripherals = (v_hscaler_v1_0 ); + OPTION driver_state = ACTIVE; + OPTION copyfiles = all; + OPTION name = v_hscaler; + OPTION version = 1.0; + +END driver diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/data/v_hscaler.tcl b/XilinxProcessorIPLib/drivers/v_hscaler/data/v_hscaler.tcl new file mode 100644 index 00000000..3a3207ea --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/data/v_hscaler.tcl @@ -0,0 +1,23 @@ +# ============================================================== +# File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC +# Version: 2015.1 +# Copyright (C) 2015 Xilinx Inc. All rights reserved. +# +# ============================================================== + +proc generate {drv_handle} { + xdefine_include_file $drv_handle "xparameters.h" "XV_hscaler" \ + "NUM_INSTANCES" \ + "DEVICE_ID" \ + "C_S_AXI_CTRL_BASEADDR" \ + "C_S_AXI_CTRL_HIGHADDR" + + xdefine_config_file $drv_handle "xv_hscaler_g.c" "XV_hscaler" \ + "DEVICE_ID" \ + "C_S_AXI_CTRL_BASEADDR" + + xdefine_canonical_xpars $drv_handle "xparameters.h" "XV_hscaler" \ + "DEVICE_ID" \ + "C_S_AXI_CTRL_BASEADDR" \ + "C_S_AXI_CTRL_HIGHADDR" +} diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/src/Makefile b/XilinxProcessorIPLib/drivers/v_hscaler/src/Makefile new file mode 100644 index 00000000..35db7f55 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/src/Makefile @@ -0,0 +1,34 @@ +# ============================================================== +# File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC +# Version: 2015.1 +# Copyright (C) 2015 Xilinx Inc. All rights reserved. +# +# ============================================================== + +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +INCLUDEFILES=*.h +LIBSOURCES=*.c +OUTS = *.o + + +libs: + echo "Compiling v_hscaler" + $(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES) + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} $(OUTS) + make clean + +include: + ${CP} $(INCLUDEFILES) $(INCLUDEDIR) + +clean: + rm -rf ${OUTS} diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler.c b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler.c new file mode 100644 index 00000000..005bf7d3 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler.c @@ -0,0 +1,407 @@ +// ============================================================== +// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC +// Version: 2015.1 +// Copyright (C) 2015 Xilinx Inc. All rights reserved. +// +// ============================================================== + +/***************************** Include Files *********************************/ +#include "xv_hscaler.h" + +/************************** Function Implementation *************************/ +#ifndef __linux__ +int XV_hscaler_CfgInitialize(XV_hscaler *InstancePtr, XV_hscaler_Config *ConfigPtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + + InstancePtr->Ctrl_BaseAddress = ConfigPtr->Ctrl_BaseAddress; + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + return XST_SUCCESS; +} +#endif + +void XV_hscaler_Start(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_AP_CTRL) & 0x80; + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_AP_CTRL, Data | 0x01); +} + +u32 XV_hscaler_IsDone(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_AP_CTRL); + return (Data >> 1) & 0x1; +} + +u32 XV_hscaler_IsIdle(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_AP_CTRL); + return (Data >> 2) & 0x1; +} + +u32 XV_hscaler_IsReady(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_AP_CTRL); + // check ap_start to see if the pcore is ready for next input + return !(Data & 0x1); +} + +void XV_hscaler_EnableAutoRestart(XV_hscaler *InstancePtr) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_AP_CTRL, 0x80); +} + +void XV_hscaler_DisableAutoRestart(XV_hscaler *InstancePtr) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_AP_CTRL, 0); +} + +void XV_hscaler_Set_HwReg_Height(XV_hscaler *InstancePtr, u32 Data) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_HEIGHT_DATA, Data); +} + +u32 XV_hscaler_Get_HwReg_Height(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_HEIGHT_DATA); + return Data; +} + +void XV_hscaler_Set_HwReg_WidthIn(XV_hscaler *InstancePtr, u32 Data) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_WIDTHIN_DATA, Data); +} + +u32 XV_hscaler_Get_HwReg_WidthIn(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_WIDTHIN_DATA); + return Data; +} + +void XV_hscaler_Set_HwReg_WidthOut(XV_hscaler *InstancePtr, u32 Data) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_WIDTHOUT_DATA, Data); +} + +u32 XV_hscaler_Get_HwReg_WidthOut(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_WIDTHOUT_DATA); + return Data; +} + +void XV_hscaler_Set_HwReg_ColorMode(XV_hscaler *InstancePtr, u32 Data) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA, Data); +} + +u32 XV_hscaler_Get_HwReg_ColorMode(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA); + return Data; +} + +void XV_hscaler_Set_HwReg_PixelRate(XV_hscaler *InstancePtr, u32 Data) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_PIXELRATE_DATA, Data); +} + +u32 XV_hscaler_Get_HwReg_PixelRate(XV_hscaler *InstancePtr) { + u32 Data; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Data = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_HWREG_PIXELRATE_DATA); + return Data; +} + +u32 XV_hscaler_Get_HwReg_hfltCoeff_BaseAddress(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return (InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE); +} + +u32 XV_hscaler_Get_HwReg_hfltCoeff_HighAddress(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return (InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH); +} + +u32 XV_hscaler_Get_HwReg_hfltCoeff_TotalBytes(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return (XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + 1); +} + +u32 XV_hscaler_Get_HwReg_hfltCoeff_BitWidth(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XV_HSCALER_CTRL_WIDTH_HWREG_HFLTCOEFF; +} + +u32 XV_hscaler_Get_HwReg_hfltCoeff_Depth(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XV_HSCALER_CTRL_DEPTH_HWREG_HFLTCOEFF; +} + +u32 XV_hscaler_Write_HwReg_hfltCoeff_Words(XV_hscaler *InstancePtr, int offset, int *data, int length) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr -> IsReady == XIL_COMPONENT_IS_READY); + + int i; + + if ((offset + length)*4 > (XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + 1)) + return 0; + + for (i = 0; i < length; i++) { + *(int *)(InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + (offset + i)*4) = *(data + i); + } + return length; +} + +u32 XV_hscaler_Read_HwReg_hfltCoeff_Words(XV_hscaler *InstancePtr, int offset, int *data, int length) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr -> IsReady == XIL_COMPONENT_IS_READY); + + int i; + + if ((offset + length)*4 > (XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + 1)) + return 0; + + for (i = 0; i < length; i++) { + *(data + i) = *(int *)(InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + (offset + i)*4); + } + return length; +} + +u32 XV_hscaler_Write_HwReg_hfltCoeff_Bytes(XV_hscaler *InstancePtr, int offset, char *data, int length) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr -> IsReady == XIL_COMPONENT_IS_READY); + + int i; + + if ((offset + length) > (XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + 1)) + return 0; + + for (i = 0; i < length; i++) { + *(char *)(InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + offset + i) = *(data + i); + } + return length; +} + +u32 XV_hscaler_Read_HwReg_hfltCoeff_Bytes(XV_hscaler *InstancePtr, int offset, char *data, int length) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr -> IsReady == XIL_COMPONENT_IS_READY); + + int i; + + if ((offset + length) > (XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + 1)) + return 0; + + for (i = 0; i < length; i++) { + *(data + i) = *(char *)(InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE + offset + i); + } + return length; +} + +u32 XV_hscaler_Get_HwReg_phasesH_V_BaseAddress(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return (InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE); +} + +u32 XV_hscaler_Get_HwReg_phasesH_V_HighAddress(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return (InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH); +} + +u32 XV_hscaler_Get_HwReg_phasesH_V_TotalBytes(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return (XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + 1); +} + +u32 XV_hscaler_Get_HwReg_phasesH_V_BitWidth(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XV_HSCALER_CTRL_WIDTH_HWREG_PHASESH_V; +} + +u32 XV_hscaler_Get_HwReg_phasesH_V_Depth(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XV_HSCALER_CTRL_DEPTH_HWREG_PHASESH_V; +} + +u32 XV_hscaler_Write_HwReg_phasesH_V_Words(XV_hscaler *InstancePtr, int offset, int *data, int length) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr -> IsReady == XIL_COMPONENT_IS_READY); + + int i; + + if ((offset + length)*4 > (XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + 1)) + return 0; + + for (i = 0; i < length; i++) { + *(int *)(InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + (offset + i)*4) = *(data + i); + } + return length; +} + +u32 XV_hscaler_Read_HwReg_phasesH_V_Words(XV_hscaler *InstancePtr, int offset, int *data, int length) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr -> IsReady == XIL_COMPONENT_IS_READY); + + int i; + + if ((offset + length)*4 > (XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + 1)) + return 0; + + for (i = 0; i < length; i++) { + *(data + i) = *(int *)(InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + (offset + i)*4); + } + return length; +} + +u32 XV_hscaler_Write_HwReg_phasesH_V_Bytes(XV_hscaler *InstancePtr, int offset, char *data, int length) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr -> IsReady == XIL_COMPONENT_IS_READY); + + int i; + + if ((offset + length) > (XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + 1)) + return 0; + + for (i = 0; i < length; i++) { + *(char *)(InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + offset + i) = *(data + i); + } + return length; +} + +u32 XV_hscaler_Read_HwReg_phasesH_V_Bytes(XV_hscaler *InstancePtr, int offset, char *data, int length) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr -> IsReady == XIL_COMPONENT_IS_READY); + + int i; + + if ((offset + length) > (XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH - XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + 1)) + return 0; + + for (i = 0; i < length; i++) { + *(data + i) = *(char *)(InstancePtr->Ctrl_BaseAddress + XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE + offset + i); + } + return length; +} + +void XV_hscaler_InterruptGlobalEnable(XV_hscaler *InstancePtr) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_GIE, 1); +} + +void XV_hscaler_InterruptGlobalDisable(XV_hscaler *InstancePtr) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_GIE, 0); +} + +void XV_hscaler_InterruptEnable(XV_hscaler *InstancePtr, u32 Mask) { + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Register = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_IER); + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_IER, Register | Mask); +} + +void XV_hscaler_InterruptDisable(XV_hscaler *InstancePtr, u32 Mask) { + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Register = XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_IER); + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_IER, Register & (~Mask)); +} + +void XV_hscaler_InterruptClear(XV_hscaler *InstancePtr, u32 Mask) { + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XV_hscaler_WriteReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_ISR, Mask); +} + +u32 XV_hscaler_InterruptGetEnabled(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_IER); +} + +u32 XV_hscaler_InterruptGetStatus(XV_hscaler *InstancePtr) { + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XV_hscaler_ReadReg(InstancePtr->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_ISR); +} diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler.h b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler.h new file mode 100644 index 00000000..054f5089 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler.h @@ -0,0 +1,131 @@ +// ============================================================== +// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC +// Version: 2015.1 +// Copyright (C) 2015 Xilinx Inc. All rights reserved. +// +// ============================================================== + +#ifndef XV_HSCALER_H +#define XV_HSCALER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#ifndef __linux__ +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xil_io.h" +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#include "xv_hscaler_hw.h" + +/**************************** Type Definitions ******************************/ +#ifdef __linux__ +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +#else +typedef struct { + u16 DeviceId; + u32 Ctrl_BaseAddress; +} XV_hscaler_Config; +#endif + +typedef struct { + u32 Ctrl_BaseAddress; + u32 IsReady; +} XV_hscaler; + +/***************** Macros (Inline Functions) Definitions *********************/ +#ifndef __linux__ +#define XV_hscaler_WriteReg(BaseAddress, RegOffset, Data) \ + Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data)) +#define XV_hscaler_ReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (RegOffset)) +#else +#define XV_hscaler_WriteReg(BaseAddress, RegOffset, Data) \ + *(volatile u32*)((BaseAddress) + (RegOffset)) = (u32)(Data) +#define XV_hscaler_ReadReg(BaseAddress, RegOffset) \ + *(volatile u32*)((BaseAddress) + (RegOffset)) + +#define Xil_AssertVoid(expr) assert(expr) +#define Xil_AssertNonvoid(expr) assert(expr) + +#define XST_SUCCESS 0 +#define XST_DEVICE_NOT_FOUND 2 +#define XST_OPEN_DEVICE_FAILED 3 +#define XIL_COMPONENT_IS_READY 1 +#endif + +/************************** Function Prototypes *****************************/ +#ifndef __linux__ +int XV_hscaler_Initialize(XV_hscaler *InstancePtr, u16 DeviceId); +XV_hscaler_Config* XV_hscaler_LookupConfig(u16 DeviceId); +int XV_hscaler_CfgInitialize(XV_hscaler *InstancePtr, XV_hscaler_Config *ConfigPtr); +#else +int XV_hscaler_Initialize(XV_hscaler *InstancePtr, const char* InstanceName); +int XV_hscaler_Release(XV_hscaler *InstancePtr); +#endif + +void XV_hscaler_Start(XV_hscaler *InstancePtr); +u32 XV_hscaler_IsDone(XV_hscaler *InstancePtr); +u32 XV_hscaler_IsIdle(XV_hscaler *InstancePtr); +u32 XV_hscaler_IsReady(XV_hscaler *InstancePtr); +void XV_hscaler_EnableAutoRestart(XV_hscaler *InstancePtr); +void XV_hscaler_DisableAutoRestart(XV_hscaler *InstancePtr); + +void XV_hscaler_Set_HwReg_Height(XV_hscaler *InstancePtr, u32 Data); +u32 XV_hscaler_Get_HwReg_Height(XV_hscaler *InstancePtr); +void XV_hscaler_Set_HwReg_WidthIn(XV_hscaler *InstancePtr, u32 Data); +u32 XV_hscaler_Get_HwReg_WidthIn(XV_hscaler *InstancePtr); +void XV_hscaler_Set_HwReg_WidthOut(XV_hscaler *InstancePtr, u32 Data); +u32 XV_hscaler_Get_HwReg_WidthOut(XV_hscaler *InstancePtr); +void XV_hscaler_Set_HwReg_ColorMode(XV_hscaler *InstancePtr, u32 Data); +u32 XV_hscaler_Get_HwReg_ColorMode(XV_hscaler *InstancePtr); +void XV_hscaler_Set_HwReg_PixelRate(XV_hscaler *InstancePtr, u32 Data); +u32 XV_hscaler_Get_HwReg_PixelRate(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_hfltCoeff_BaseAddress(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_hfltCoeff_HighAddress(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_hfltCoeff_TotalBytes(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_hfltCoeff_BitWidth(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_hfltCoeff_Depth(XV_hscaler *InstancePtr); +u32 XV_hscaler_Write_HwReg_hfltCoeff_Words(XV_hscaler *InstancePtr, int offset, int *data, int length); +u32 XV_hscaler_Read_HwReg_hfltCoeff_Words(XV_hscaler *InstancePtr, int offset, int *data, int length); +u32 XV_hscaler_Write_HwReg_hfltCoeff_Bytes(XV_hscaler *InstancePtr, int offset, char *data, int length); +u32 XV_hscaler_Read_HwReg_hfltCoeff_Bytes(XV_hscaler *InstancePtr, int offset, char *data, int length); +u32 XV_hscaler_Get_HwReg_phasesH_V_BaseAddress(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_phasesH_V_HighAddress(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_phasesH_V_TotalBytes(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_phasesH_V_BitWidth(XV_hscaler *InstancePtr); +u32 XV_hscaler_Get_HwReg_phasesH_V_Depth(XV_hscaler *InstancePtr); +u32 XV_hscaler_Write_HwReg_phasesH_V_Words(XV_hscaler *InstancePtr, int offset, int *data, int length); +u32 XV_hscaler_Read_HwReg_phasesH_V_Words(XV_hscaler *InstancePtr, int offset, int *data, int length); +u32 XV_hscaler_Write_HwReg_phasesH_V_Bytes(XV_hscaler *InstancePtr, int offset, char *data, int length); +u32 XV_hscaler_Read_HwReg_phasesH_V_Bytes(XV_hscaler *InstancePtr, int offset, char *data, int length); + +void XV_hscaler_InterruptGlobalEnable(XV_hscaler *InstancePtr); +void XV_hscaler_InterruptGlobalDisable(XV_hscaler *InstancePtr); +void XV_hscaler_InterruptEnable(XV_hscaler *InstancePtr, u32 Mask); +void XV_hscaler_InterruptDisable(XV_hscaler *InstancePtr, u32 Mask); +void XV_hscaler_InterruptClear(XV_hscaler *InstancePtr, u32 Mask); +u32 XV_hscaler_InterruptGetEnabled(XV_hscaler *InstancePtr); +u32 XV_hscaler_InterruptGetStatus(XV_hscaler *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_hw.h b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_hw.h new file mode 100644 index 00000000..53018a91 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_hw.h @@ -0,0 +1,77 @@ +// ============================================================== +// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC +// Version: 2015.1 +// Copyright (C) 2015 Xilinx Inc. All rights reserved. +// +// ============================================================== + +// CTRL +// 0x0000 : Control signals +// bit 0 - ap_start (Read/Write/COH) +// bit 1 - ap_done (Read/COR) +// bit 2 - ap_idle (Read) +// bit 3 - ap_ready (Read) +// bit 7 - auto_restart (Read/Write) +// others - reserved +// 0x0004 : Global Interrupt Enable Register +// bit 0 - Global Interrupt Enable (Read/Write) +// others - reserved +// 0x0008 : IP Interrupt Enable Register (Read/Write) +// bit 0 - Channel 0 (ap_done) +// bit 1 - Channel 1 (ap_ready) +// others - reserved +// 0x000c : IP Interrupt Status Register (Read/TOW) +// bit 0 - Channel 0 (ap_done) +// bit 1 - Channel 1 (ap_ready) +// others - reserved +// 0x0010 : Data signal of HwReg_Height +// bit 15~0 - HwReg_Height[15:0] (Read/Write) +// others - reserved +// 0x0014 : reserved +// 0x0018 : Data signal of HwReg_WidthIn +// bit 15~0 - HwReg_WidthIn[15:0] (Read/Write) +// others - reserved +// 0x001c : reserved +// 0x0020 : Data signal of HwReg_WidthOut +// bit 15~0 - HwReg_WidthOut[15:0] (Read/Write) +// others - reserved +// 0x0024 : reserved +// 0x0028 : Data signal of HwReg_ColorMode +// bit 7~0 - HwReg_ColorMode[7:0] (Read/Write) +// others - reserved +// 0x002c : reserved +// 0x0030 : Data signal of HwReg_PixelRate +// bit 31~0 - HwReg_PixelRate[31:0] (Read/Write) +// 0x0034 : reserved +// 0x0400 ~ +// 0x07ff : Memory 'HwReg_hfltCoeff' (384 * 16b) +// Word n : bit [15: 0] - HwReg_hfltCoeff[2n] +// bit [31:16] - HwReg_hfltCoeff[2n+1] +// 0x2000 ~ +// 0x3fff : Memory 'HwReg_phasesH_V' (1920 * 18b) +// Word n : bit [17:0] - HwReg_phasesH_V[n] +// others - reserved +// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake) + +#define XV_HSCALER_CTRL_ADDR_AP_CTRL 0x0000 +#define XV_HSCALER_CTRL_ADDR_GIE 0x0004 +#define XV_HSCALER_CTRL_ADDR_IER 0x0008 +#define XV_HSCALER_CTRL_ADDR_ISR 0x000c +#define XV_HSCALER_CTRL_ADDR_HWREG_HEIGHT_DATA 0x0010 +#define XV_HSCALER_CTRL_BITS_HWREG_HEIGHT_DATA 16 +#define XV_HSCALER_CTRL_ADDR_HWREG_WIDTHIN_DATA 0x0018 +#define XV_HSCALER_CTRL_BITS_HWREG_WIDTHIN_DATA 16 +#define XV_HSCALER_CTRL_ADDR_HWREG_WIDTHOUT_DATA 0x0020 +#define XV_HSCALER_CTRL_BITS_HWREG_WIDTHOUT_DATA 16 +#define XV_HSCALER_CTRL_ADDR_HWREG_COLORMODE_DATA 0x0028 +#define XV_HSCALER_CTRL_BITS_HWREG_COLORMODE_DATA 8 +#define XV_HSCALER_CTRL_ADDR_HWREG_PIXELRATE_DATA 0x0030 +#define XV_HSCALER_CTRL_BITS_HWREG_PIXELRATE_DATA 32 +#define XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_BASE 0x0400 +#define XV_HSCALER_CTRL_ADDR_HWREG_HFLTCOEFF_HIGH 0x07ff +#define XV_HSCALER_CTRL_WIDTH_HWREG_HFLTCOEFF 16 +#define XV_HSCALER_CTRL_DEPTH_HWREG_HFLTCOEFF 384 +#define XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_BASE 0x2000 +#define XV_HSCALER_CTRL_ADDR_HWREG_PHASESH_V_HIGH 0x3fff +#define XV_HSCALER_CTRL_WIDTH_HWREG_PHASESH_V 18 +#define XV_HSCALER_CTRL_DEPTH_HWREG_PHASESH_V 1920 diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_l2.c b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_l2.c new file mode 100644 index 00000000..0a00b44e --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_l2.c @@ -0,0 +1,598 @@ +/****************************************************************************** + * + * 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 THE + * XILINX CONSORTIUM 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 xv_hscaler_l2.c +* +* The Horizontal Scaler Layer-2 Driver. +* The functions in this file provides an abstraction from the register peek/poke +* methodology by implementing most common use-case provided by the sub-core. +* See xv_hscaler_l2.h for a detailed description of the layer-2 driver +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00  rc   05/01/15   Initial Release
+
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#include +#include "xv_hscaler_l2.h" + +/************************** Constant Definitions *****************************/ +#define PI (3.14159265358979) +#define STEP_PRECISION (65536) // 2^16 +#define COEFF_PRECISION (4096) // 2^12 +#define COEFF_QUANT (4096) + +/* Mask definitions for Low and high 16 bits in a 32 bit number */ +#define XMASK_LOW_16BITS (0x0000FFFF) +#define XMASK_HIGH_16BITS (0xFFFF0000) + + +/**************************** Type Definitions *******************************/ + +/**************************** Local Global *******************************/ +static float SincCoeffs[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS]; +static float TempCoeffs[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS]; +static float WinCoeffs[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS]; +static float NormCoeffs[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS]; + +int HSC_SAMPLES_PER_CLOCK = 2; +int HSC_MAX_WIDTH = 4096; +int STEP_PRECISION_SHIFT = 16; +int HSC_PHASE_SHIFT = 6; + +/************************** Function Prototypes ******************************/ +static float hamming( int x, int taps); +static float sinc(float x); +static void CalculatePhases(XV_hscaler_l2 *pHscL2Data, + u32 WidthIn, + u32 WidthOut, + u32 PixelRate); +static void XV_HScalerGetCoeff(XV_hscaler *InstancePtr, + XV_hscaler_l2 *pHscL2Data, + u32 WidthIn, + u32 WidthOut, + u32 PixPerClk); +static void XV_HScalerSetCoeff(XV_hscaler *InstancePtr, + XV_hscaler_l2 *pHscL2Data); + +/*****************************************************************************/ +/** +* This function starts the horizontal scaler core +* +* @param InstancePtr is a pointer to the core instance to be worked on. +* +* @return None +* +******************************************************************************/ +void XV_HScalerStart(XV_hscaler *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + + XV_hscaler_EnableAutoRestart(InstancePtr); + XV_hscaler_Start(InstancePtr); +} + +/*****************************************************************************/ +/** +* This function stops the horizontal scaler core +* +* @param InstancePtr is a pointer to the core instance to be worked on. +* +* @return None +* +******************************************************************************/ +void XV_HScalerStop(XV_hscaler *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + + XV_hscaler_DisableAutoRestart(InstancePtr); +} + +/*****************************************************************************/ +/** +* This function applies the hamming filter on specified pixel position +* +* @param x is the pixel coordinate in horizontal direction +* @param taps is the number of taps available to the scaler +* +* @return hamming filter result +* +******************************************************************************/ +static float hamming( int x, int taps) +{ + //0.54 + 0.46 * cos(pi * x / filter_size); 0.54 - 0.46 * cos(2*pi * x / filter_size) + return (float) (0.54 + (0.46*cos((PI*x)/(taps+1)))); +} + +/*****************************************************************************/ +/** +* This function applies the SIN function to specified pixel position +* +* @param x is the pixel coordinate in horizontal direction +* +* @return Sine function result +* +******************************************************************************/ +static float sinc(float x) +{ + if (x==0) + return 1; + + return (float) sin(x*PI)/(float)(x*PI); +} + +/*****************************************************************************/ +/** +* This function calculates the phases for 1 line. Same phase info is used for +* full frame +* +* @param WidthIn is the input frame width +* @param WidthOut is the scaled frame width +* @param PixelRate is the number of pixels per clock being processed +* +* @return None +* +******************************************************************************/ +static void CalculatePhases(XV_hscaler_l2 *pHscL2Data, + u32 WidthIn, + u32 WidthOut, + u32 PixelRate) +{ + int loopWidth; + loopWidth = ((WidthIn > WidthOut) ? WidthIn +(HSC_SAMPLES_PER_CLOCK-1) : WidthOut +(HSC_SAMPLES_PER_CLOCK-1))/HSC_SAMPLES_PER_CLOCK; + + int x, s; + int offset = 0; + int xWritePos = 0; + int OutputWriteEn; + int GetNewPix; + int PhaseH; + int arrayIdx; + int xReadPos = 0; + int nrRds = 0; + int nrRdsClck = 0; + + arrayIdx = 0; + for (x=0; xphasesH[x] = 0; + nrRdsClck = 0; + for (s=0; s>(STEP_PRECISION_SHIFT-HSC_PHASE_SHIFT)) & (XV_HSCALER_MAX_H_PHASES-1);//(HSC_PHASES-1); + GetNewPix = 0; + OutputWriteEn = 0; + if ((offset >> STEP_PRECISION_SHIFT) != 0) + { + // read a new input sample + GetNewPix = 1; + offset = offset - (1<> STEP_PRECISION_SHIFT) == 0) && (xWritePos< WidthOut)) + { + // produce a new output sample + offset += PixelRate; + OutputWriteEn = 1; + xWritePos++; + } + //printf("x %5d, offset %5d, phase %5d, arrayIdx %5d, readpos %5d writepos %5d rden %3d wren %3d\n", (int)x*HSC_SAMPLES_PER_CLOCK+s, offset, (int)PhaseH, (int)arrayIdx, (int)xReadPos, xWritePos, GetNewPix, OutputWriteEn); + pHscL2Data->phasesH[x] = pHscL2Data->phasesH[x] | (PhaseH << (s*9)); + pHscL2Data->phasesH[x] = pHscL2Data->phasesH[x] | (arrayIdx << (6 + (s*9))); + pHscL2Data->phasesH[x] = pHscL2Data->phasesH[x] | (OutputWriteEn << (8 + (s*9))); + + if (GetNewPix) nrRdsClck++; + } + if (arrayIdx>=HSC_SAMPLES_PER_CLOCK) arrayIdx &= (HSC_SAMPLES_PER_CLOCK-1); + + //printf("%d nrRds per clock %d left hanging\n", nrRdsClck, nrRds); + nrRds += nrRdsClck; + if (nrRds>=HSC_SAMPLES_PER_CLOCK) + { + nrRds -= HSC_SAMPLES_PER_CLOCK; + //printf("getting %d new samples\n", HSC_SAMPLES_PER_CLOCK); + } + } +} + +/*****************************************************************************/ +/** +* This function loads user defined filter coefficients in the scaler coefficient +* storage +* +* @param InstancePtr is a pointer to the core instance to be worked on. +* @param pHscL2Data is a pointer to the core instance layer 2 data. +* @param HCoeff is the user defined filter coefficients +******************************************************************************/ +void XV_HscalerLoadUsrCoeffients(XV_hscaler *InstancePtr, + XV_hscaler_l2 *pHscL2Data, + const short HCoeff[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS]) +{ + int i,j,k, pad, offset; + int num_phases = XV_HSCALER_MAX_H_PHASES; + int num_taps = pHscL2Data->EffectiveTaps; + + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(pHscL2Data != NULL); + Xil_AssertVoid((pHscL2Data->EffectiveTaps > 0) && + (pHscL2Data->EffectiveTaps <= XV_HSCALER_MAX_H_TAPS)); + + //determine if coefficient needs padding (effective vs. max taps) + pad = XV_HSCALER_MAX_H_TAPS - num_taps; + offset = ((pad) ? (pad>>1) : 0); + + //Load User defined coefficients into scaler coefficient table + for (i = 0; i < num_phases; i++) + { + for (k=0,j=offset; jcoeff[i][j] = HCoeff[i][k]; + } + } + + if(pad) //effective taps < max_taps + { + for (i = 0; i < num_phases; i++) + { + //pad left + for (j = 0; j < offset; j++) + { + pHscL2Data->coeff[i][j] = 0; + } + //pad right + for (j = (num_taps+offset); j < XV_HSCALER_MAX_H_TAPS; j++) + { + pHscL2Data->coeff[i][j] = 0; + } + } + } +} + +/*****************************************************************************/ +/** +* This function computes the filter coefficients based on scaling ratio and +* stores them into the layer 2 data storage +* +* @param InstancePtr is a pointer to the core instance to be worked on. +* @param pVscL2Data is a pointer to the core instance layer 2 data. +* @param HeightIn is the input frame height +* @param HeightOut is the scaled frame height +* +* @return None +* +******************************************************************************/ +static void XV_HScalerGetCoeff(XV_hscaler *InstancePtr, + XV_hscaler_l2 *pHscL2Data, + u32 WidthIn, + u32 WidthOut, + u32 PixPerClk) +{ + int num_phases = XV_HSCALER_MAX_H_PHASES; + int num_taps = pHscL2Data->EffectiveTaps; + int center_tap = num_taps/2; + int i,j, pad, offset; + float x, fc; + float sum[XV_HSCALER_MAX_H_PHASES]; + float cos_win[XV_HSCALER_MAX_H_TAPS]; + + /* + * Assert validates the input arguments + */ + Xil_AssertVoid((pHscL2Data->EffectiveTaps > 0) && + (pHscL2Data->EffectiveTaps <= XV_HSCALER_MAX_H_TAPS)); + + if(WidthIn < WidthOut) + { + fc = (float)WidthIn/(float)WidthOut; + } + else + { + fc = (float)WidthOut/(float)WidthIn; + } + + //determine if coefficient needs padding (effective vs. max taps) + pad = XV_HSCALER_MAX_H_TAPS - num_taps; + offset = ((pad) ? (pad>>1) : 0); + + for(i=0; iFilterSel) + { + case XV_HFILT_LANCZOS: + //Window is a sinc function instead of cosine function + // if using lanczos2 or lanczos3 kernel + // lanczos(x) = sinc(x) * sinc(x / filter_size); + + for (i = 0; i < num_phases; i++) + { + for (j = 0; j < num_taps; j++) + { + x = TempCoeffs[i][j]; + WinCoeffs[i][j] = SincCoeffs[i][j] * sinc((fc*x)/num_taps); + } + } + break; + + case XV_HFILT_WINDOWED_SINC: + for (j = 1; j <= num_taps; j++) + { + cos_win[j-1] = hamming(j, num_taps); + } + + for (i = 0; i < num_phases; i++) + { + for (j = 0; j < num_taps; j++) + { + WinCoeffs[i][j] = SincCoeffs[i][j] * cos_win[j]; + } + } + break; + } + + // normalize to unity and quantize + for (i = 0; i < num_phases; i++) + { + sum[i] = 0; + for (j = 0; j < num_taps; j++) + { + sum[i] += WinCoeffs[i][j]; + } + } + + for (i = 0; i < num_phases; i++) + { + for (j = offset; j < num_taps; j++) + { + NormCoeffs[i][j] = WinCoeffs[i][j]/sum[i]; + pHscL2Data->coeff[i][j] = (short) ((NormCoeffs[i][j] * COEFF_QUANT) + 0.5); + } + } + + if(pad) //effective taps < max_taps + { + for (i = 0; i < num_phases; i++) + { + //pad left + for (j = 0; j < offset; j++) + { + pHscL2Data->coeff[i][j] = 0; + } + //pad right + for (j = (num_taps+offset); j < XV_HSCALER_MAX_H_TAPS; j++) + { + pHscL2Data->coeff[i][j] = 0; + } + } + } +} + +/*****************************************************************************/ +/** +* This function programs the computed filter coefficients and phase data into +* core registers +* +* @param InstancePtr is a pointer to the core instance to be worked on. +* @param HCoeff is the array that holds computed coefficients +* +* @return None +* +* @Note This version of driver does not make use of computed coefficients. +* Pre-computed coefficients are stored in a local table which are used +* to overwrite any computed coefficients before being programmed into +* the core registers. Control flow still computes the coefficients to +* maintain the sw latency for driver version which would eventually use +* computed coefficients +******************************************************************************/ +static void XV_HScalerSetCoeff(XV_hscaler *InstancePtr, + XV_hscaler_l2 *pHscL2Data) +{ + int num_phases = XV_HSCALER_MAX_H_PHASES; + int num_taps = XV_HSCALER_MAX_H_TAPS/2; + int val,i,j; + u32 baseAddr; + + baseAddr = XV_hscaler_Get_HwReg_hfltCoeff_BaseAddress(InstancePtr); + for (i = 0; i < num_phases; i++) + { + for(j=0; j< num_taps; j++) + { + val = (pHscL2Data->coeff[i][(j*2)+1] << 16) | (pHscL2Data->coeff[i][j*2] & XMASK_LOW_16BITS); + Xil_Out32(baseAddr+((i*num_taps+j)*4), val); + } + } + + //program phases + baseAddr = XV_hscaler_Get_HwReg_phasesH_V_BaseAddress(InstancePtr); + for (i = 0; i < (HSC_MAX_WIDTH/HSC_SAMPLES_PER_CLOCK); i++) + { + Xil_Out32(baseAddr+(i*4), pHscL2Data->phasesH[i]); + } +} + +/*****************************************************************************/ +/** +* This function configures the scaler core registers with the specified +* configuration parameters of the axi stream +* +* @param InstancePtr is a pointer to the core instance to be worked on. +* @param HeightIn is the input stream height +* @param WidthIn is the input stream width +* @param WidthOut is the output stream width +* @param cformat is the input stream color format +* +* @return None +* +******************************************************************************/ +void XV_HScalerSetup(XV_hscaler *InstancePtr, + XV_hscaler_l2 *pHscL2Data, + u32 HeightIn, + u32 WidthIn, + u32 WidthOut, + u32 PixPerClk, + u32 cformat) +{ + u32 PixelRate; + + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(pHscL2Data != NULL); + + PixelRate = (u32) ((float)((WidthIn * STEP_PRECISION) + (WidthOut/2))/(float)WidthOut); + + /* Compute Phase for 1 line */ + CalculatePhases(pHscL2Data, WidthIn, WidthOut, PixelRate); + + if(pHscL2Data->ScalerType == XV_HSCALER_POLYPHASE) + { + if(!pHscL2Data->UseExtCoeff) //No predefined coefficients + { + /* Generate coefficients for horizontal scaling ratio */ + XV_HScalerGetCoeff(InstancePtr, + pHscL2Data, + WidthIn, + WidthOut, + PixPerClk); + } + + /* Program generated coefficients into the IP register bank */ + XV_HScalerSetCoeff(InstancePtr, pHscL2Data); + } + + XV_hscaler_Set_HwReg_Height(InstancePtr, HeightIn); + XV_hscaler_Set_HwReg_WidthIn(InstancePtr, WidthIn); + XV_hscaler_Set_HwReg_WidthOut(InstancePtr, WidthOut); + XV_hscaler_Set_HwReg_ColorMode(InstancePtr, cformat); + XV_hscaler_Set_HwReg_PixelRate(InstancePtr, PixelRate); +} + + +/*****************************************************************************/ +/** +* +* This function prints H Scaler status on the console +* +* @param InstancePtr is the instance pointer to the core instance. +* +* @return None +* +******************************************************************************/ +void XV_HScalerDbgReportStatus(XV_hscaler *InstancePtr) +{ + XV_hscaler *pHsc = InstancePtr; + u32 done, idle, ready, ctrl; + u32 widthin, widthout, heightin, pixrate, cformat; + u32 type = 3; //hard-coded to polyphase for now + u32 baseAddr, taps, phases; + int val,i,j; + + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + xil_printf("\r\n\r\n----->H SCALER IP STATUS<----\r\n"); + done = XV_hscaler_IsDone(pHsc); + idle = XV_hscaler_IsIdle(pHsc); + ready = XV_hscaler_IsReady(pHsc); + ctrl = XV_hscaler_ReadReg(pHsc->Ctrl_BaseAddress, XV_HSCALER_CTRL_ADDR_AP_CTRL); + + heightin = XV_hscaler_Get_HwReg_Height(pHsc); + widthin = XV_hscaler_Get_HwReg_WidthIn(pHsc); + widthout = XV_hscaler_Get_HwReg_WidthOut(pHsc); +// type = XV_hscaler_Get_Hwreg_scaletype_v(pHsc); + cformat = XV_hscaler_Get_HwReg_ColorMode(pHsc); + pixrate = XV_hscaler_Get_HwReg_PixelRate(pHsc); + + taps = XV_HSCALER_MAX_H_TAPS/2; + phases = XV_HSCALER_MAX_H_PHASES; + xil_printf("IsDone: %d\r\n", done); + xil_printf("IsIdle: %d\r\n", idle); + xil_printf("IsReady: %d\r\n", ready); + xil_printf("Ctrl: 0x%x\r\n\r\n", ctrl); + + xil_printf("Input Height: %d\r\n",heightin); + xil_printf("Input Width: %d\r\n",widthin); + xil_printf("Output Width: %d\r\n",widthout); +// xil_printf("Scaler Type: %d\r\n",type); + xil_printf("Color Format: %d\r\n",cformat); + xil_printf("Pixel Rate: %d\r\n",pixrate); + xil_printf("Num Phases: %d\r\n",phases); + xil_printf("Num Taps: %d\r\n",taps*2); + + if(type == 3) + { + short lsb, msb; + + xil_printf("\r\nCoefficients:"); + + baseAddr = XV_hscaler_Get_HwReg_hfltCoeff_BaseAddress(pHsc); + for(i = 0; i < phases; i++) + { + xil_printf("\r\nPhase %2d: ",i); + for(j=0; j< taps; j++) + { + val = Xil_In32(baseAddr+((i*taps+j)*4)); + + //coefficients are 12-bits + lsb = (short)(val & XMASK_LOW_16BITS); + msb = (short)((val & XMASK_HIGH_16BITS)>>16); + + xil_printf("%5d %5d ", lsb, msb); + } + } + } +} diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_l2.h b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_l2.h new file mode 100644 index 00000000..8d65f1dd --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_l2.h @@ -0,0 +1,185 @@ +/****************************************************************************** + * + * 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 THE + * XILINX CONSORTIUM 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 xv_hscaler_l2.h +* +* This header file contains layer 2 API's of the horizontal scaler sub-core +* driver.The functions contained herein provides a high level implementation of +* features provided by the IP, abstracting away the register level details from +* the user +* +* H Scaler IP Features +* +* This H-Scaler IP supports following features +* - 3 Channel Scaler with RGB, YUV444 and YUV422 support +* - Scale horizontally to 4K line at 60Hz +* - up to 16bits color depth +* - 1, 2 or 4 pixel per clock processing +* +* Dependency +* +* This driver makes use of the video enumerations and data types defined in the +* Xilinx Video Common Driver (video_common_vX.x) and as such the common driver +* must be included as dependency to compile this driver + +* Initialization & Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate to the hscaler core. +* +* Before using the layer-2 API's user must initialize the core by calling +* Layer-1 API XV_hscaler_Initialize(). This function will look for a +* configuration structure for the device and initialize it to defined HW +* settings. After initialization Layer-2 API's can be used to configure +* the core. It is recommended user always make use of Layer-2 API to +* interact with this core. +* Advanced users always have the capability to directly interact with the IP +* core using Layer-1 API's that perform low level register peek/poke. +* +* Interrupts +* +* This driver does not have any interrupts +* +* Virtual Memory +* +* This driver supports Virtual Memory. The RTOS is responsible for calculating +* the correct device base address in Virtual Memory space. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Limitations +* +* Current implementation of "computed coefficients" is non-entrant. If multiple +* instances of the core are used in the design, user application has to make sure +* that scaler configuration is an atomic operation and cannot be interrupted in +* middle to context switch to a different instance of the core +* However fixed coefficient version of the code (default) is safe to be used with +* multiple instances of the core. +* i.e. SCALER_FIXED_COEFF should always be 1 +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00  rc   05/01/15   Initial Release
+
+* 
+* +******************************************************************************/ +#ifndef XV_HSCALER_L2_H /* prevent circular inclusions */ +#define XV_HSCALER_L2_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "xvidc.h" +#include "xv_hscaler.h" + +/************************** Constant Definitions *****************************/ +/** @name Hw Configuration + * @{ + * The following constants define the scaler HW configuration + * TODO: + * Below defined Parameters are static configuration of H Scaler IP + * The tool needs to export these parameters to SDK and the driver will + * be populated with these option settings. i.e. these settings could be + * accessible via instance pointer + * + */ +#define XV_HSCALER_MAX_H_TAPS (6) +#define XV_HSCALER_MAX_H_PHASES (64) + +/**************************** Type Definitions *******************************/ +/** + * This typedef contains the Scaler Type + */ +typedef enum +{ + XV_HSCALER_BILINEAR = 0, + XV_HSCALER_BICUBIC, + XV_HSCALER_POLYPHASE +}XV_HSCALER_TYPE; + +/** + * This typedef contains the type of filters available for scaling operation + */ +typedef enum +{ + XV_HFILT_LANCZOS = 0, + XV_HFILT_WINDOWED_SINC +}XV_HFILTER_ID; + +/** + * V Scaler Layer 2 data. The user is required to allocate a variable + * of this type for every V Scaler device in the system. A pointer to a + * variable of this type is then passed to the driver API functions. + */ +typedef struct +{ + u8 EffectiveTaps; + u8 UseExtCoeff; + XV_HFILTER_ID FilterSel; + XV_HSCALER_TYPE ScalerType; + u8 Gain; + short coeff[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS]; + u32 phasesH[4096]; +}XV_hscaler_l2; + + +/************************** Function Prototypes ******************************/ +void XV_HScalerStart(XV_hscaler *InstancePtr); +void XV_HScalerStop(XV_hscaler *InstancePtr); +void XV_HscalerLoadUsrCoeffients(XV_hscaler *InstancePtr, + XV_hscaler_l2 *pHscL2Data, + const short HCoeff[XV_HSCALER_MAX_H_PHASES][XV_HSCALER_MAX_H_TAPS]); +void XV_HScalerSetup(XV_hscaler *InstancePtr, + XV_hscaler_l2 *pHscL2Data, + u32 HeightIn, + u32 WidthIn, + u32 WidthOut, + u32 PixPerClk, + u32 cformat); + +void XV_HScalerDbgReportStatus(XV_hscaler *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_linux.c b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_linux.c new file mode 100644 index 00000000..85b468d3 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_linux.c @@ -0,0 +1,150 @@ +// ============================================================== +// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC +// Version: 2015.1 +// Copyright (C) 2015 Xilinx Inc. All rights reserved. +// +// ============================================================== + +#ifdef __linux__ + +/***************************** Include Files *********************************/ +#include "xv_hscaler.h" + +/***************** Macros (Inline Functions) Definitions *********************/ +#define MAX_UIO_PATH_SIZE 256 +#define MAX_UIO_NAME_SIZE 64 +#define MAX_UIO_MAPS 5 +#define UIO_INVALID_ADDR 0 + +/**************************** Type Definitions ******************************/ +typedef struct { + u32 addr; + u32 size; +} XV_hscaler_uio_map; + +typedef struct { + int uio_fd; + int uio_num; + char name[ MAX_UIO_NAME_SIZE ]; + char version[ MAX_UIO_NAME_SIZE ]; + XV_hscaler_uio_map maps[ MAX_UIO_MAPS ]; +} XV_hscaler_uio_info; + +/***************** Variable Definitions **************************************/ +static XV_hscaler_uio_info uio_info; + +/************************** Function Implementation *************************/ +static int line_from_file(char* filename, char* linebuf) { + char* s; + int i; + FILE* fp = fopen(filename, "r"); + if (!fp) return -1; + s = fgets(linebuf, MAX_UIO_NAME_SIZE, fp); + fclose(fp); + if (!s) return -2; + for (i=0; (*s)&&(iuio_num); + return line_from_file(file, info->name); +} + +static int uio_info_read_version(XV_hscaler_uio_info* info) { + char file[ MAX_UIO_PATH_SIZE ]; + sprintf(file, "/sys/class/uio/uio%d/version", info->uio_num); + return line_from_file(file, info->version); +} + +static int uio_info_read_map_addr(XV_hscaler_uio_info* info, int n) { + int ret; + char file[ MAX_UIO_PATH_SIZE ]; + info->maps[n].addr = UIO_INVALID_ADDR; + sprintf(file, "/sys/class/uio/uio%d/maps/map%d/addr", info->uio_num, n); + FILE* fp = fopen(file, "r"); + if (!fp) return -1; + ret = fscanf(fp, "0x%x", &info->maps[n].addr); + fclose(fp); + if (ret < 0) return -2; + return 0; +} + +static int uio_info_read_map_size(XV_hscaler_uio_info* info, int n) { + int ret; + char file[ MAX_UIO_PATH_SIZE ]; + sprintf(file, "/sys/class/uio/uio%d/maps/map%d/size", info->uio_num, n); + FILE* fp = fopen(file, "r"); + if (!fp) return -1; + ret = fscanf(fp, "0x%x", &info->maps[n].size); + fclose(fp); + if (ret < 0) return -2; + return 0; +} + +int XV_hscaler_Initialize(XV_hscaler *InstancePtr, const char* InstanceName) { + XV_hscaler_uio_info *InfoPtr = &uio_info; + struct dirent **namelist; + int i, n; + char* s; + char file[ MAX_UIO_PATH_SIZE ]; + char name[ MAX_UIO_NAME_SIZE ]; + int flag = 0; + + assert(InstancePtr != NULL); + + n = scandir("/sys/class/uio", &namelist, 0, alphasort); + if (n < 0) return XST_DEVICE_NOT_FOUND; + for (i = 0; i < n; i++) { + strcpy(file, "/sys/class/uio/"); + strcat(file, namelist[i]->d_name); + strcat(file, "/name"); + if ((line_from_file(file, name) == 0) && (strcmp(name, InstanceName) == 0)) { + flag = 1; + s = namelist[i]->d_name; + s += 3; // "uio" + InfoPtr->uio_num = atoi(s); + break; + } + } + if (flag == 0) return XST_DEVICE_NOT_FOUND; + + uio_info_read_name(InfoPtr); + uio_info_read_version(InfoPtr); + for (n = 0; n < MAX_UIO_MAPS; ++n) { + uio_info_read_map_addr(InfoPtr, n); + uio_info_read_map_size(InfoPtr, n); + } + + sprintf(file, "/dev/uio%d", InfoPtr->uio_num); + if ((InfoPtr->uio_fd = open(file, O_RDWR)) < 0) { + return XST_OPEN_DEVICE_FAILED; + } + + // NOTE: slave interface 'Ctrl' should be mapped to uioX/map0 + InstancePtr->Ctrl_BaseAddress = (u32)mmap(NULL, InfoPtr->maps[0].size, PROT_READ|PROT_WRITE, MAP_SHARED, InfoPtr->uio_fd, 0 * getpagesize()); + assert(InstancePtr->Ctrl_BaseAddress); + + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + return XST_SUCCESS; +} + +int XV_hscaler_Release(XV_hscaler *InstancePtr) { + XV_hscaler_uio_info *InfoPtr = &uio_info; + + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + munmap((void*)InstancePtr->Ctrl_BaseAddress, InfoPtr->maps[0].size); + + close(InfoPtr->uio_fd); + + return XST_SUCCESS; +} + +#endif diff --git a/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_sinit.c b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_sinit.c new file mode 100644 index 00000000..5cb3af01 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/v_hscaler/src/xv_hscaler_sinit.c @@ -0,0 +1,45 @@ +// ============================================================== +// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC +// Version: 2015.1 +// Copyright (C) 2015 Xilinx Inc. All rights reserved. +// +// ============================================================== + +#ifndef __linux__ + +#include "xstatus.h" +#include "xparameters.h" +#include "xv_hscaler.h" + +extern XV_hscaler_Config XV_hscaler_ConfigTable[]; + +XV_hscaler_Config *XV_hscaler_LookupConfig(u16 DeviceId) { + XV_hscaler_Config *ConfigPtr = NULL; + + int Index; + + for (Index = 0; Index < XPAR_XV_HSCALER_NUM_INSTANCES; Index++) { + if (XV_hscaler_ConfigTable[Index].DeviceId == DeviceId) { + ConfigPtr = &XV_hscaler_ConfigTable[Index]; + break; + } + } + + return ConfigPtr; +} + +int XV_hscaler_Initialize(XV_hscaler *InstancePtr, u16 DeviceId) { + XV_hscaler_Config *ConfigPtr; + + Xil_AssertNonvoid(InstancePtr != NULL); + + ConfigPtr = XV_hscaler_LookupConfig(DeviceId); + if (ConfigPtr == NULL) { + InstancePtr->IsReady = 0; + return (XST_DEVICE_NOT_FOUND); + } + + return XV_hscaler_CfgInitialize(InstancePtr, ConfigPtr); +} + +#endif