In our last project we have successfully got the HDMI output up and running and displaying a test pattern curtesy of the test pattern generator. In this project we are going to update that based design to include support for a MIPI camera using the FMC Pcam adapter and a PCam 5C camera.
This will then provide a image pass through solution which can be used as the basis for testing out image processing algorithms by dropping them into the processing core.
Vivado DesignThe starting block design can be seen below and contains the following elements
- MicroBlaze
- UART - For communication
- Test Pattern Generator
- Video Timing Controller
- AXI Stream to Video Out
- Video Processing Sub System
- Memory Interface Generator
This is the base of the design we are going to modify, into it we need to add in the following IP
- Video Frame Buffer Write
- Video Frame Buffer Read
- Sensor Demosaic
- MIPI CSI-2 RX Subsystem
- AXI Interrupt controller
The completed diagram can be seen below
The configurations for the IP cores are
MIPI CSI2 RX Subsystem
Sensor Demosaic
Frame Buffer Write
Frame Buffer Read
AXI Interrupt Controller
The clocking is as below
150 MHz clock is the AXI Stream clock and Pixel Output Clock
200 MHz clock is the reference for the MIPI and MIG
AXI Lite and MicroBlaze are clocked from the MIG UI Clock (100 MHz in this case)
Once the design is completed we can build the XSA and export it for inclusion in Vitis.
We also need to update the XDC constraints to include the new IO
set_property PACKAGE_PIN V22 [get_ports {HDMI_R_D[7]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_R_D[7]}]
set_property PACKAGE_PIN Y23 [get_ports {HDMI_R_D[6]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_R_D[6]}]
set_property PACKAGE_PIN Y22 [get_ports {HDMI_R_D[5]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_R_D[5]}]
set_property PACKAGE_PIN AB24 [get_ports {HDMI_R_D[4]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_R_D[4]}]
set_property PACKAGE_PIN AC24 [get_ports {HDMI_R_D[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_R_D[3]}]
set_property PACKAGE_PIN AB25 [get_ports {HDMI_R_D[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_R_D[2]}]
set_property PACKAGE_PIN AA25 [get_ports {HDMI_R_D[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_R_D[1]}]
set_property PACKAGE_PIN AA23 [get_ports {HDMI_R_D[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_R_D[0]}]
set_property PACKAGE_PIN V23 [get_ports {HDMI_G_D[7]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_G_D[7]}]
set_property PACKAGE_PIN Y20 [get_ports {HDMI_G_D[6]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_G_D[6]}]
set_property PACKAGE_PIN U24 [get_ports {HDMI_G_D[5]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_G_D[5]}]
set_property PACKAGE_PIN W20 [get_ports {HDMI_G_D[4]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_G_D[4]}]
set_property PACKAGE_PIN W23 [get_ports {HDMI_G_D[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_G_D[3]}]
set_property PACKAGE_PIN U20 [get_ports {HDMI_G_D[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_G_D[2]}]
set_property PACKAGE_PIN V24 [get_ports {HDMI_G_D[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_G_D[1]}]
set_property PACKAGE_PIN U25 [get_ports {HDMI_G_D[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_G_D[0]}]
set_property PACKAGE_PIN U26 [get_ports {HDMI_B_D[7]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_B_D[7]}]
set_property PACKAGE_PIN W24 [get_ports {HDMI_B_D[6]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_B_D[6]}]
set_property PACKAGE_PIN W25 [get_ports {HDMI_B_D[5]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_B_D[5]}]
set_property PACKAGE_PIN W26 [get_ports {HDMI_B_D[4]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_B_D[4]}]
set_property PACKAGE_PIN V26 [get_ports {HDMI_B_D[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_B_D[3]}]
set_property PACKAGE_PIN Y26 [get_ports {HDMI_B_D[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_B_D[2]}]
set_property PACKAGE_PIN Y25 [get_ports {HDMI_B_D[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_B_D[1]}]
set_property PACKAGE_PIN AA24 [get_ports {HDMI_B_D[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {HDMI_B_D[0]}]
set_property PACKAGE_PIN AB26 [get_ports HDMI_R_DE]
set_property IOSTANDARD LVCMOS18 [get_ports HDMI_R_DE]
set_property PACKAGE_PIN AC26 [get_ports HDMI_R_VSYNC]
set_property IOSTANDARD LVCMOS18 [get_ports HDMI_R_VSYNC]
set_property PACKAGE_PIN V21 [get_ports HDMI_R_CLK]
set_property IOSTANDARD LVCMOS18 [get_ports HDMI_R_CLK]
set_property PACKAGE_PIN AA22 [get_ports HDMI_R_HSYNC]
set_property IOSTANDARD LVCMOS18 [get_ports HDMI_R_HSYNC]
set_property PACKAGE_PIN N18 [get_ports IIC_MAIN_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC_MAIN_scl_io]
set_property PACKAGE_PIN K25 [get_ports IIC_MAIN_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC_MAIN_sda_io]
set_property IOSTANDARD LVDS_25 [get_ports mipi_phy_if_0_clk_hs_p]
set_property IOSTANDARD LVCMOS25 [get_ports mipi_phy_if_0_clk_lp_n]
set_property IOSTANDARD LVCMOS25 [get_ports mipi_phy_if_0_clk_lp_p]
set_property IOSTANDARD LVCMOS25 [get_ports {mipi_phy_if_0_data_lp_n[1]}]
set_property IOSTANDARD LVCMOS25 [get_ports {mipi_phy_if_0_data_lp_n[0]}]
set_property IOSTANDARD LVCMOS25 [get_ports {mipi_phy_if_0_data_lp_p[1]}]
set_property IOSTANDARD LVCMOS25 [get_ports {mipi_phy_if_0_data_lp_p[0]}]
set_property IOSTANDARD LVDS_25 [get_ports {mipi_phy_if_0_data_hs_p[1]}]
set_property IOSTANDARD LVDS_25 [get_ports {mipi_phy_if_0_data_hs_p[0]}]
set_property PACKAGE_PIN E17 [get_ports mipi_phy_if_0_clk_hs_p]
set_property PACKAGE_PIN G19 [get_ports {mipi_phy_if_0_data_hs_p[1]}]
set_property PACKAGE_PIN A17 [get_ports {mipi_phy_if_0_data_hs_p[0]}]
set_property PACKAGE_PIN C17 [get_ports mipi_phy_if_0_clk_lp_p]
set_property PACKAGE_PIN B17 [get_ports mipi_phy_if_0_clk_lp_n]
set_property PACKAGE_PIN D20 [get_ports {mipi_phy_if_0_data_lp_n[1]}]
set_property PACKAGE_PIN F17 [get_ports {mipi_phy_if_0_data_lp_n[0]}]
set_property PACKAGE_PIN G17 [get_ports {mipi_phy_if_0_data_lp_p[0]}]
set_property PACKAGE_PIN E20 [get_ports {mipi_phy_if_0_data_lp_p[1]}]
set_property DIFF_TERM TRUE [get_ports mipi_phy_if_0_clk_hs_p]
set_property DIFF_TERM TRUE [get_ports mipi_phy_if_0_clk_hs_n]
set_property DIFF_TERM TRUE [get_ports {mipi_phy_if_0_data_hs_n[1]}]
set_property DIFF_TERM TRUE [get_ports {mipi_phy_if_0_data_hs_n[0]}]
set_property DIFF_TERM TRUE [get_ports {mipi_phy_if_0_data_hs_p[1]}]
set_property DIFF_TERM TRUE [get_ports {mipi_phy_if_0_data_hs_p[0]}]
set_property IOSTANDARD LVCMOS25 [get_ports {cam_pwr_up[0]}]
set_property PACKAGE_PIN H16 [get_ports {cam_pwr_up[0]}]
set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
connect_debug_port dbg_hub/clk [get_nets clk]
SW DevelopmentThe Software application must do the following stages
- Initialise the peripherals
- Configure the I2C switch for the HDMI channel
- Configure the HDMI device
- Configure the I2C switch for the FMC Channel
- Configure the I2C Switch on the FMC PCam Adapter for the first camera
- Initialize the VPSS
- Configure the Video Timing Generator for 1080p 60 FPS
- Configure the Video Frame Read Buffer
- Configure the Video Frame Write Buffer
- Configure the Demosaic
- Configure the MIPI CSI-2 RX Subsystem
- Start the IP cores
The completed application is below
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xstatus.h"
#include "sleep.h"
#include "xiic_l.h"
#include "xil_io.h"
#include "xil_types.h"
#include "xvtc.h"
#include "function_prototype.h"
#include "pcam_5C_cfgs.h"
//#include "xv_tpg.h"
#include "xvidc.h"
#include "vga.h"
#include "xvprocss.h"
#include "xv_demosaic.h"
#define PAGE_SIZE 16
#include "xv_frmbufwr.h"
#include "xv_frmbufrd.h"
#define DDR_BASEADDR XPAR_MIG7SERIES_0_BASEADDR
#define XVFRMBUFWR_BUFFER_BASEADDR (DDR_BASEADDR + (0x1000000))
XV_frmbufwr frmbufwr;
XV_frmbufwr_Config frmbufwr_cfg;
XV_frmbufrd frmbufrd;
XV_frmbufrd_Config frmbufrd_cfg;
#define IIC_BASE_ADDRESS XPAR_IIC_0_BASEADDR
#define EEPROM_TEST_START_ADDRESS 0x80
#define IIC_SWITCH_ADDRESS 0x74
#define IIC_ADV7511_ADDRESS 0x39
XV_demosaic InstancePtr;
XV_demosaic_Config *demosaic_Config;
XVtc VtcInst;
XVtc_Config *vtc_config ;
//XV_tpg tpg;
//XV_tpg_Config *tpg_config;
XVprocSs scaler_new_inst;
XVprocSs csc_new_inst;
VideoMode video;
typedef u8 AddressType;
typedef struct {
u8 addr;
u8 data;
u8 init;
} HDMI_REG;
#define NUMBER_OF_HDMI_REGS 16
HDMI_REG hdmi_iic[NUMBER_OF_HDMI_REGS] = {
{0x41, 0x00, 0x10},
{0x98, 0x00, 0x03},
{0x9A, 0x00, 0xE0},
{0x9C, 0x00, 0x30},
{0x9D, 0x00, 0x61},
{0xA2, 0x00, 0xA4},
{0xA3, 0x00, 0xA4},
{0xE0, 0x00, 0xD0},
{0xF9, 0x00, 0x00},
{0x18, 0x00, 0xE7},
{0x55, 0x00, 0x00},
{0x56, 0x00, 0x28},
{0xD6, 0x00, 0xC0},
{0xAF, 0x00, 0x4},
{0xF9, 0x00, 0x00}
};
extern XIic IicAdapter;
u8 EepromIicAddr; /* Variable for storing Eeprom IIC address */
int IicLowLevelDynEeprom();
u8 EepromReadByte(AddressType Address, u8 *BufferPtr, u8 ByteCount);
u8 EepromWriteByte(AddressType Address, u8 *BufferPtr, u8 ByteCount);
//HDMI IIC
int IicLowLevelDynEeprom()
{
u8 BytesRead;
u32 StatusReg;
u8 Index;
int Status;
u32 i;
u8 channel[1] = {0x20};
u8 PCAM_FMC_addr = 0x70;
u8 PCAM_FMC_ch = 0x01;
Status = XIic_DynInit(IIC_BASE_ADDRESS);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
xil_printf("\r\nAfter XIic_DynInit\r\n");
while (((StatusReg = XIic_ReadReg(IIC_BASE_ADDRESS,
XIIC_SR_REG_OFFSET)) &
(XIIC_SR_RX_FIFO_EMPTY_MASK |
XIIC_SR_TX_FIFO_EMPTY_MASK |
XIIC_SR_BUS_BUSY_MASK)) !=
(XIIC_SR_RX_FIFO_EMPTY_MASK |
XIIC_SR_TX_FIFO_EMPTY_MASK)) {
}
EepromIicAddr = IIC_SWITCH_ADDRESS;
XIic_DynSend(IIC_BASE_ADDRESS, EepromIicAddr,
channel, sizeof(channel), XIIC_STOP);
EepromIicAddr = IIC_ADV7511_ADDRESS;
for ( Index = 0; Index < NUMBER_OF_HDMI_REGS; Index++)
{
EepromWriteByte(hdmi_iic[Index].addr, &hdmi_iic[Index].init, 1);
}
for ( Index = 0; Index < NUMBER_OF_HDMI_REGS; Index++)
{
BytesRead = EepromReadByte(hdmi_iic[Index].addr, &hdmi_iic[Index].data, 1);
for(i=0;i<1000;i++) {}; // IIC delay
if (BytesRead != 1) {
return XST_FAILURE;
}
}
channel[0] = 0x02;
EepromIicAddr = IIC_SWITCH_ADDRESS;
XIic_DynSend(IIC_BASE_ADDRESS, EepromIicAddr,
channel, sizeof(channel), XIIC_STOP);
channel[0] = PCAM_FMC_ch;
EepromIicAddr = PCAM_FMC_addr;
XIic_DynSend(IIC_BASE_ADDRESS, EepromIicAddr,
channel, sizeof(channel), XIIC_STOP);
return XST_SUCCESS;
}
u8 EepromReadByte(AddressType Address, u8 *BufferPtr, u8 ByteCount)
{
u8 ReceivedByteCount;
u8 SentByteCount;
u16 StatusReg;
/*
* Position the Read pointer to specific location in the EEPROM.
*/
do {
StatusReg = XIic_ReadReg(IIC_BASE_ADDRESS, XIIC_SR_REG_OFFSET);
if (!(StatusReg & XIIC_SR_BUS_BUSY_MASK)) {
SentByteCount = XIic_DynSend(IIC_BASE_ADDRESS, EepromIicAddr,
(u8 *) &Address, sizeof(Address), XIIC_REPEATED_START);
}
} while (SentByteCount != sizeof(Address));
/*
* Receive the data.
*/
ReceivedByteCount = XIic_DynRecv(IIC_BASE_ADDRESS, EepromIicAddr,
BufferPtr, ByteCount);
/*
* Return the number of bytes received from the EEPROM.
*/
return ReceivedByteCount;
}
u8 EepromWriteByte(AddressType Address, u8 *BufferPtr, u8 ByteCount)
{
u8 SentByteCount;
u8 WriteBuffer[sizeof(Address) + PAGE_SIZE];
u8 Index;
/*
* A temporary write buffer must be used which contains both the address
* and the data to be written, put the address in first based upon the
* size of the address for the EEPROM
*/
if (sizeof(AddressType) == 2) {
WriteBuffer[0] = (u8) (Address >> 8);
WriteBuffer[1] = (u8) (Address);
} else if (sizeof(AddressType) == 1) {
WriteBuffer[0] = (u8) (Address);
EepromIicAddr |= (EEPROM_TEST_START_ADDRESS >> 8) & 0x7;
}
/*
* Put the data in the write buffer following the address.
*/
for (Index = 0; Index < ByteCount; Index++) {
WriteBuffer[sizeof(Address) + Index] = BufferPtr[Index];
}
/*
* Write a page of data at the specified address to the EEPROM.
*/
SentByteCount = XIic_DynSend(IIC_BASE_ADDRESS, EepromIicAddr,
WriteBuffer, sizeof(Address) + ByteCount,
XIIC_STOP);
/*
* Return the number of bytes written to the EEPROM.
*/
return SentByteCount - sizeof(Address);
}
void InitVprocSs_CSC() {
XVprocSs_Config* p_vpss_cfg1;
int status, Status;
int widthIn, heightIn, widthOut, heightOut;
widthOut = 1920;
heightOut = 1080;
// Local variables
XVidC_VideoMode resIdIn, resIdOut;
XVidC_VideoStream StreamIn, StreamOut;
widthIn = 1920;
heightIn = 1080;
StreamIn.FrameRate = 60; //rao
p_vpss_cfg1 = XVprocSs_LookupConfig(XPAR_XVPROCSS_0_DEVICE_ID);
if (p_vpss_cfg1 == NULL) {
xil_printf("ERROR! Failed to find VPSS-based scaler.\n\r");
return;
}
status = XVprocSs_CfgInitialize(&csc_new_inst, p_vpss_cfg1,
p_vpss_cfg1->BaseAddress);
if (status != XST_SUCCESS) {
xil_printf("ERROR! Failed to initialize VPSS-based scaler.\n\r");
return;
}
XVprocSs_Stop(&csc_new_inst);
//Initialize FMC, Adapter and Sensor IIC
Status = InitIIC();
if (Status != XST_SUCCESS) {
xil_printf("\n\r IIC initialization Failed \n\r");
return XST_FAILURE;
}
xil_printf("IIC Initializtion Done \n\r");
// Get resolution ID from frame size
resIdIn = XVidC_GetVideoModeId(widthIn, heightIn, StreamIn.FrameRate,
FALSE);
// Setup Video Processing Subsystem
StreamIn.VmId = resIdIn;
StreamIn.Timing.HActive = widthIn;
StreamIn.Timing.VActive = heightIn;
StreamIn.ColorFormatId = XVIDC_CSF_RGB;
StreamIn.ColorDepth = csc_new_inst.Config.ColorDepth;
StreamIn.PixPerClk = csc_new_inst.Config.PixPerClock;
StreamIn.IsInterlaced = 0;
status = XVprocSs_SetVidStreamIn(&csc_new_inst, &StreamIn);
if (status != XST_SUCCESS) {
xil_printf("Unable to set input video stream parameters correctly\r\n");
return;
}
// Get resolution ID from frame size
resIdOut = XVidC_GetVideoModeId(widthOut, heightOut, 60, FALSE);
if (resIdOut != XVIDC_VM_1920x1080_60_P) {
xil_printf("resIdOut %d doesn't match XVIDC_VM_1920x1080_60_P\r\n",
resIdOut);
}
StreamOut.VmId = resIdOut;
StreamOut.Timing.HActive = widthOut;
StreamOut.Timing.VActive = heightOut;
StreamOut.ColorFormatId = XVIDC_CSF_YCRCB_444;
StreamOut.ColorDepth = csc_new_inst.Config.ColorDepth;
StreamOut.PixPerClk = csc_new_inst.Config.PixPerClock;
StreamOut.FrameRate = 60;
StreamOut.IsInterlaced = 0;
XVprocSs_SetVidStreamOut(&csc_new_inst, &StreamOut);
if (status != XST_SUCCESS) {
xil_printf("Unable to set output video stream parameters correctly\r\n");
return;
}
status = XVprocSs_SetSubsystemConfig(&csc_new_inst);
if (status != XST_SUCCESS) {
xil_printf("xvprocss_SetSubsystemConfig failed %d\r\n", status);
return;
}
//XVprocSs_ReportSubsystemConfig(&scaler_new_inst);
XVprocSs_Start(&scaler_new_inst);
}
int main()
{
XVtc_Timing vtcTiming;
int Status;
XVtc_SourceSelect SourceSelect;
init_platform();
int pcam5c_mode = 1;
print("Hello World\n\r");
print("Successfully ran Hello World application");
Status = IicLowLevelDynEeprom();
if (Status != XST_SUCCESS) {
xil_printf("ADV7511 IIC programming FAILED\r\n");
return XST_FAILURE;
}
xil_printf("ADV7511 IIC programming PASSED\r\n");
vtc_config = XVtc_LookupConfig(XPAR_VTC_0_DEVICE_ID);
XVtc_CfgInitialize(&VtcInst, vtc_config, vtc_config->BaseAddress);
video = VMODE_1920x1080 ;
vtcTiming.HActiveVideo = video.width; /**< Horizontal Active Video Size */
vtcTiming.HFrontPorch = video.hps - video.width; /**< Horizontal Front Porch Size */
vtcTiming.HSyncWidth = video.hpe - video.hps; /**< Horizontal Sync Width */
vtcTiming.HBackPorch = video.hmax - video.hpe + 1; /**< Horizontal Back Porch Size */
vtcTiming.HSyncPolarity = video.hpol; /**< Horizontal Sync Polarity */
vtcTiming.VActiveVideo = video.height; /**< Vertical Active Video Size */
vtcTiming.V0FrontPorch = video.vps - video.height; /**< Vertical Front Porch Size */
vtcTiming.V0SyncWidth = video.vpe - video.vps; /**< Vertical Sync Width */
vtcTiming.V0BackPorch = video.vmax - video.vpe + 1;; /**< Horizontal Back Porch Size */
vtcTiming.V1FrontPorch = video.vps - video.height; /**< Vertical Front Porch Size */
vtcTiming.V1SyncWidth = video.vpe - video.vps; /**< Vertical Sync Width */
vtcTiming.V1BackPorch = video.vmax - video.vpe + 1;; /**< Horizontal Back Porch Size */
vtcTiming.VSyncPolarity = video.vpol; /**< Vertical Sync Polarity */
vtcTiming.Interlaced = 0;
memset((void *)&SourceSelect, 0, sizeof(SourceSelect));
SourceSelect.VBlankPolSrc = 1;
SourceSelect.VSyncPolSrc = 1;
SourceSelect.HBlankPolSrc = 1;
SourceSelect.HSyncPolSrc = 1;
SourceSelect.ActiveVideoPolSrc = 1;
SourceSelect.ActiveChromaPolSrc= 1;
SourceSelect.VChromaSrc = 1;
SourceSelect.VActiveSrc = 1;
SourceSelect.VBackPorchSrc = 1;
SourceSelect.VSyncSrc = 1;
SourceSelect.VFrontPorchSrc = 1;
SourceSelect.VTotalSrc = 1;
SourceSelect.HActiveSrc = 1;
SourceSelect.HBackPorchSrc = 1;
SourceSelect.HSyncSrc = 1;
SourceSelect.HFrontPorchSrc = 1;
SourceSelect.HTotalSrc = 1;
XVtc_RegUpdateEnable(&VtcInst);
XVtc_SetGeneratorTiming(&VtcInst, &vtcTiming);
XVtc_SetSource(&VtcInst, &SourceSelect);
XVtc_EnableGenerator(&VtcInst);
XVtc_Enable(&VtcInst);
u32 height,width,status;
InitVprocSs_CSC();
//Initialize Adapter Interrupt System
Status = SetupAdapterInterruptSystem(&IicAdapter);
if (Status != XST_SUCCESS) {
xil_printf("\n\rInterrupt System Initialization Failed \n\r");
return XST_FAILURE;
}
xil_printf("Adapter Interrupt System Initialization Done \n\r");
//Set up IIC Interrupt Handlers
SetupIICIntrHandlers();
xil_printf("IIC Interrupt Handlers Setup Done \n\r");
//Set Address of Adapter IIC
Status = SetAdapterIICAddress();
if (Status != XST_SUCCESS) {
xil_printf("\n\rAdapter IIC Address Setup Failed \n\r");
return XST_FAILURE;
}
xil_printf("Adapter IIC Address Set\n\r");
Status = InitializeCsiRxSs();
if (Status != XST_SUCCESS) {
xil_printf("CSI Rx Ss Init failed status = %x.\r\n", Status);
return XST_FAILURE;
}
//Preconfigure Sensor
Status = SensorPreConfig(pcam5c_mode);
if (Status != XST_SUCCESS) {
xil_printf("\n\rSensor PreConfiguration Failed \n\r");
return XST_FAILURE;
}
xil_printf("\n\rSensor is PreConfigured\n\r");
demosaic_Config = XV_demosaic_LookupConfig(XPAR_V_DEMOSAIC_0_DEVICE_ID);
XV_demosaic_CfgInitialize(&InstancePtr, demosaic_Config,
demosaic_Config->BaseAddress);
XV_demosaic_Set_HwReg_width(&InstancePtr, 1920);
XV_demosaic_Set_HwReg_height(&InstancePtr, 1080);
XV_demosaic_Set_HwReg_bayer_phase(&InstancePtr, 0x3);
XV_demosaic_EnableAutoRestart(&InstancePtr);
XV_demosaic_Start(&InstancePtr);
//Enables the sensors.
WritetoReg(0x30, 0x08, 0x02);
XV_frmbufwr_Initialize(&frmbufwr, XPAR_V_FRMBUF_WR_0_DEVICE_ID);
XV_frmbufwr_Set_HwReg_width(&frmbufwr, 1920);
XV_frmbufwr_Set_HwReg_height(&frmbufwr, 1080);
XV_frmbufwr_Set_HwReg_stride(&frmbufwr, 4*1920);
XV_frmbufwr_Set_HwReg_video_format(&frmbufwr, XVIDC_CSF_MEM_RGB8);
XV_frmbufwr_Set_HwReg_frm_buffer_V(&frmbufwr, XVFRMBUFWR_BUFFER_BASEADDR);
XV_frmbufwr_EnableAutoRestart(&frmbufwr);
XV_frmbufwr_Start(&frmbufwr);
XV_frmbufrd_Initialize(&frmbufrd, XPAR_V_FRMBUF_RD_0_DEVICE_ID);
XV_frmbufrd_Set_HwReg_width(&frmbufrd, 1920);
XV_frmbufrd_Set_HwReg_height(&frmbufrd, 1080);
XV_frmbufrd_Set_HwReg_stride(&frmbufrd, 4*1920);
XV_frmbufrd_Set_HwReg_video_format(&frmbufrd, XVIDC_CSF_MEM_RGB8);
XV_frmbufrd_Set_HwReg_frm_buffer_V(&frmbufrd, XVFRMBUFWR_BUFFER_BASEADDR);
XV_frmbufrd_EnableAutoRestart(&frmbufrd);
XV_frmbufrd_Start(&frmbufrd);
while(1){
}
cleanup_platform();
return 0;
}
TestingWhen this is deployed on the hardware target with the FMC PCam Adapter and the PCam camera the images where displayed as would be expected on the HDMI Display.
Now we have an image processing system we can work with for testing algorithms
Comments