MicroZed Chronicles: MIPI Imaging on Zynq - Part 2
In a previous installment, we built the Vivado element of an image processing system to be deployed on a Trenz ZynqBerry Zero module. I like this module because it enables a small form factor while also providing HDMI and MIPI interfaces. Of course, as you can see from the previous implementation, the device is fairly full but there is still room to sneak in additional functionality if we wanted to do some image processing.
With the Vivado application completed, we can now export the XSA with the BIT file into a Vitis project. In Vitis, we can create an application which uses the exported XSA as the platform.
We need to configure the Pcam 5C camera over a I2C link. The ZynqBerry Zero contains a I2C multiplexer which can switch the Zynq PS I2C bus between the GPIO or the CSI interface (see schematic). To be able to communicate over the I2C link with the Pcam 5C, the application software needs to control this switch to ensure the I2C bus is correctly routed on the board.
Along with controlling the I2C switch, the SW application must also perform the following:
Initialize the PS I2C.
Initialize the video timing controller.
Set the I2C switch to route to channel one.
Detect the camera using I2C.
Initialize the camera over I2C.
Initialize the video timing controller for 720P.
Initialize and configure the VDMA for 720P. Remember the RGB pixel is 24 BITs long so the horizontal size and stride need to be set to the width * 3. This is how the stride and horizontal size are defined in bytes.
Configure the frame buffer to store the captured frame in the DDR memory.
Configure the frame buffer to read out the captured frame and output the data over the TMDS RGB to DVI interface.
Here, I should note that as I was commissioning this application, I noticed that several of the TDMS pins have had their polarity swapped to ease routing. The inverted signals are TMDS_CLK P/N and TMDS_data P/N [1:0]. We need to set the appropriate channel inversion option in the TMDS IP core within the Vivado design to correctly obtain the image. Failure to do this will result in some interesting color schemes, as green and blue channels will be switched along with red and white. If the red / white swap makes you scratch your head, it’s because the blue and green channels are output as zero when the red channel is driven. The inversion also causes the blue and green channels to show as full scale, which makes the display appear white.
Correctly implementing the inversion will not show this issue.
Once the application is built, we can download the ELF and we should see an output on the display with the Pcam 5C and HDMI connected.
Now of course, we need to build a BIN file to be able to store the application in the QSPI and boot without the need of JTAG. This can easily be done in Vitis from the Xilinx menu and by selecting Create Boot File with the system project selected.
With the BIT file created, the final step is to program the QSPI on the board. We can do this either in Vivado or Vitis. We will be doing it in Vitis for this application. Vitis will select the correct Boot.bin just created and the FSBL.elf from the platform.
This will program the flash memory with the application just created and ensure that the image captured by the camera is output onto the connected display.
I have uploaded the Vivado design and Vitis SW application to my GitHub.