Skip to content
Montopoli Group · Est. 1986

How to connect a 3.4 inch 480x480 TFT LCD display to a FPGA?

By admin

How to connect a 3.4 inch 480x480 TFT LCD display to a FPGA

To connect a 3.4 inch 480x480 tft lcd display to an FPGA, you need to handle the interface protocol, typically MIPI DSI (Display Serial Interface) or parallel RGB, depending on the specific model. For the 3.4 inch 480x480 tft lcd display from DisplayModule, it uses a 2-lane MIPI DSI interface, which is common for small-to-medium-sized displays. The FPGA must have MIPI D-PHY transceivers, either built-in (like in Xilinx Artix-7 or Zynq-7000 series with MIPI support) or via an external PHY chip like the TI SN65DSI84. The display requires a 1.8V I/O voltage for the MIPI lanes and a 2.8V to 3.3V for the backlight and power supply. The resolution is 480x480 pixels, with a 24-bit color depth (RGB888), meaning each pixel requires 24 bits of data. The refresh rate is typically 60 Hz, so the pixel clock frequency is around 14.4 MHz (480 x 480 x 60 = 13.824 MHz, plus blanking overhead). For MIPI DSI, the data rate per lane is about 200 Mbps to 500 Mbps, depending on the blanking configuration. The FPGA must generate the MIPI DSI packets, including video mode packets (like long packets for pixel data and short packets for synchronization). The display’s datasheet specifies the timing parameters: horizontal front porch (HFP) of 10 pixels, horizontal sync pulse (HSP) of 10 pixels, horizontal back porch (HBP) of 20 pixels, vertical front porch (VFP) of 10 lines, vertical sync pulse (VSP) of 10 lines, and vertical back porch (VBP) of 20 lines. This gives a total horizontal period of 480 + 10 + 10 + 20 = 520 pixels, and a vertical period of 480 + 10 + 10 + 20 = 520 lines. The actual pixel clock is 520 x 520 x 60 = 16.224 MHz. The MIPI DSI interface uses a differential pair for each lane (data lanes and clock lane), with a characteristic impedance of 100 ohms. The FPGA’s output must have a common-mode voltage of 200 mV and a differential swing of 200 mV to 400 mV. If your FPGA lacks native MIPI support, you can use a bridge chip like the LT8912B or the SN65DSI84, which converts parallel RGB to MIPI DSI. The parallel RGB interface from the FPGA would need 24 data lines (R, G, B each 8 bits), a pixel clock, and horizontal/vertical sync signals. The bridge chip then serializes this data into two MIPI lanes. Power supply: the display requires 3.3V for the backlight (typically 20 mA to 30 mA) and 2.8V to 3.3V for the logic (around 10 mA to 15 mA). The MIPI lanes need 1.8V for the D-PHY. Use a low-dropout regulator (LDO) like the AMS1117-3.3 for the backlight and a separate LDO for the 1.8V. The FPGA’s I/O banks must be configured to 1.8V for the MIPI signals. For the backlight, a PWM signal from the FPGA (frequency 1 kHz to 10 kHz) can control brightness via a transistor or MOSFET. The display’s reset pin is active low, so you need to hold it low for at least 10 ms after power-up, then release. The initialization sequence for the MIPI display involves sending command packets via DSI short packets (8-bit commands) like 0x11 (sleep out), 0x29 (display on), and 0x36 (memory data access control) for orientation. The command set is specific to the display driver IC, which is often the ILI9488 or similar for 480x480 panels. For example, the ILI9488 requires a 120 ms delay after sleep out. The FPGA must implement a state machine to handle the MIPI DSI protocol, including the low-power mode (LP) for commands and high-speed mode (HS) for video data. The DSI specification defines the packet format: a 32-bit header (8-bit data identifier, 16-bit word count, 8-bit ECC), followed by data bytes (for long packets), and a 16-bit CRC. The FPGA logic can be written in Verilog or VHDL, using a PLL to generate the pixel clock and the MIPI bit clock. For example, if the pixel clock is 16.224 MHz, the MIPI bit clock per lane is 16.224 MHz x 24 bits per pixel / 2 lanes = 194.688 MHz. This is within the range of most FPGA PLLs. The D-PHY uses a DDR (double data rate) scheme, so the FPGA’s SERDES (serializer/deserializer) must output data on both edges of the clock. In Xilinx devices, you can use the OSERDESE2 primitive for the MIPI lanes. The output must be differential, so use an OBUFDS or similar buffer. For the clock lane, you need a differential clock output at the same frequency as the bit clock. The display’s datasheet specifies the MIPI timing: the HS clock frequency is 200 MHz typical, but for 480x480 at 60 Hz, it’s lower. The lane data rate is 194.688 Mbps, which is within the D-PHY spec (80 Mbps to 1 Gbps). The FPGA must also handle the MIPI DSI video mode, where the packetized data is sent as a stream of long packets for each row. Each row of 480 pixels requires 480 x 24 / 8 = 1440 bytes of data, plus the packet header (4 bytes) and footer (2 bytes), so 1446 bytes per row. The total data per frame is 480 x 1446 = 694,080 bytes, at 60 Hz that’s 41.64 MB/s. The MIPI interface bandwidth is 2 lanes x 194.688 Mbps = 389.376 Mbps, which is 48.672 MB/s, so there’s headroom. The blanking intervals (HFP, HBP, etc.) are used to insert null packets or sync packets. The FPGA must generate the correct sync pulses: for each row, a short packet (0x01 for horizontal sync) is sent, followed by the pixel data long packet, then a blanking period. For the vertical sync, a short packet (0x02) is sent. The timing is critical: the FPGA’s state machine must count pixels and lines to match the display’s timing. Use a counter for the horizontal period (520 pixels) and vertical period (520 lines). The pixel data is read from a frame buffer in the FPGA’s block RAM or external memory (like DDR3). For a 480x480 frame with 24-bit color, each frame requires 480 x 480 x 3 = 691,200 bytes. If you use double buffering, you need 1.38 MB of memory. Most FPGAs have enough block RAM (e.g., Xilinx Artix-7 has up to 3.6 MB), but you can also use an external SDRAM. The frame buffer can be updated from a microcontroller or a camera interface. The FPGA must also handle the MIPI DSI command mode for initialization, but for video, it’s easier to use video mode. The display’s datasheet provides the register settings for the driver IC. For example, the ILI9488 requires setting the pixel format (0x3A) to 0x66 (18-bit) or 0x77 (24-bit), and the interface mode (0xB0) to 0x00 for MIPI. The FPGA can send these commands via DSI short packets with the data type 0x15 (generic short write). The command sequence is: power up, wait 10 ms, reset low for 10 ms, release reset, wait 120 ms, send sleep out (0x11), wait 120 ms, send display on (0x29), wait 50 ms, then start video mode. For the backlight, use a PWM frequency of 5 kHz, with a duty cycle from 0% to 100%. The FPGA’s PWM module can be a simple counter with a compare register. The display’s backlight voltage is 3.3V, and the current is 20 mA, so a simple NPN transistor like the 2N2222 can drive it. The FPGA’s GPIO pin (3.3V) can drive the base through a 1k resistor. The MIPI traces on the PCB must be length-matched within 0.5 mm to avoid skew. The differential impedance should be 100 ohms, so use a stackup with a 4-layer board: top layer for signals, ground plane, power plane, bottom layer. The trace width for 100 ohms on a standard FR4 board (1.6 mm thick, 0.2 mm prepreg) is about 0.2 mm with 0.2 mm spacing. The FPGA’s I/O standards must be set to LVDS or MIPI D-PHY. In Xilinx Vivado, you can use the “MIPI_DPHY” primitive if available, but for older FPGAs, you need to manually instantiate the differential buffers. The clock lane uses a differential clock with a frequency of 194.688 MHz, and the data lanes use DDR outputs. The FPGA’s PLL must generate this frequency from a reference clock (e.g., 50 MHz). The multiplication factor is 194.688 / 50 = 3.89376, which is not integer, so you might need a fractional PLL or use a different reference clock like 27 MHz. With 27 MHz, the multiplier is 7.21, still fractional. A better approach is to use a 20 MHz reference, then multiply by 9.7344, but that’s still fractional. The MIPI spec allows a tolerance of ±1000 ppm, so you can use an integer multiplier with a small error. For example, use a 16.224 MHz pixel clock from a 50 MHz PLL: 50 MHz / 625 * 203 = 16.224 MHz (203/625 ratio). The MIPI bit clock is 194.688 MHz, which is 50 MHz / 125 * 486.72, not integer. In practice, you can use a 200 MHz MIPI clock and adjust the blanking to match the frame rate. For 200 MHz bit clock, the pixel clock is 200 MHz / 24 * 2 = 16.667 MHz, and the frame rate becomes 16.667 MHz / (520 * 520) = 61.6 Hz, which is acceptable. The FPGA’s PLL can generate 200 MHz from 50 MHz with a multiplier of 4 (200 MHz). The pixel clock is then 200 MHz / 12 = 16.667 MHz (using a counter). The horizontal and vertical timings need to be adjusted: total pixels per line = 16.667 MHz / 60 Hz / 520 lines = 534.6 pixels, so you can use 535 pixels per line, with HFP=15, HSP=10, HBP=20, active=480, total=525. Then vertical total = 520 lines, so frame rate = 16.667 MHz / (525 * 520) = 61.0 Hz. The display’s datasheet typically allows a range of 55 Hz to 65 Hz, so this is fine. The MIPI data rate is 200 Mbps per lane, and the total bandwidth is 400 Mbps, which is enough for the 16.667 MHz pixel clock (16.667 MHz * 24 bits = 400 Mbps exactly). So the FPGA’s PLL is set to 200 MHz, and the pixel clock is derived by dividing by 12. The MIPI lane clock is 200 MHz, and the data is DDR, so the bit rate is 200 Mbps per lane. The FPGA’s SERDES must be configured for 10-bit or 8-bit depth? The D-PHY uses 8-bit symbols, but the data is 24-bit RGB, so you need to send 3 bytes per pixel. The MIPI DSI packet format encodes the data as 8-bit bytes, so the serialization is straightforward. The FPGA’s OSERDESE2 can be set to 8:1 serialization, meaning 8 bits are serialized into a single lane at 200 Mbps. For 24 bits per pixel, you need 3 OSERDESE2 instances per lane, but since the data is sent in parallel, you can use a 24-bit shift register. The Xilinx primitive for MIPI is the “MIPI_DPHY” in the 7 series, but it’s not available in all devices. For Artix-7, you can use the “IOBUFDS” for the differential output and “OSERDESE2” for the serialization. The clock lane uses a “ODDR” primitive to generate the DDR clock. The FPGA’s logic must include a FIFO to buffer the pixel data from the frame buffer. The FIFO depth should be at least one row (1440 bytes) to avoid underflow. The MIPI DSI controller can be implemented as a state machine: idle, send sync packet, send pixel data, send blanking. The sync packet is a short packet with data type 0x01 (horizontal sync) or 0x02 (vertical sync). The pixel data is a long packet with data type 0x3E (packed pixel data, 24-bit). The packet header includes the word count (1440 bytes for 480 pixels). The FPGA must calculate the CRC for the packet. The CRC polynomial is x^16 + x^12 + x^5 + 1 (0x1021). The ECC for the header is a 6-bit code. The DSI specification details the algorithm. For simplicity, you can use a lookup table for the CRC. The FPGA’s block RAM can store the frame data, and the MIPI controller reads it row by row. The frame buffer can be updated via a UART or SPI interface from a microcontroller. For example, a simple UART at 115200 baud can send pixel data, but it would take 691,200 bytes / 115200 = 6 seconds per frame, so it’s only for static images. For real-time video, use a camera interface or a high-speed USB. The FPGA’s logic can also handle touch input if the display has a touch controller (e.g., FT6336). The touch controller communicates via I2C, so the FPGA can implement an I2C master to read the touch coordinates. The I2C address is 0x38, and the data is 5 bytes per touch point. The FPGA can then send the touch data to a host via UART. The display’s power consumption is about 100 mW for the backlight and 50 mW for the logic, so total 150 mW. The FPGA’s power consumption depends on the logic usage, but typically 500 mW to 1 W for a small design. Use a 3.3V regulator with 500 mA capacity, and a 1.8V regulator with 200 mA capacity. The backlight can be driven by a constant current source, but a simple resistor is fine for prototyping. The FPGA’s pinout must be assigned to the correct I/O banks. For MIPI, use a bank with 1.8V VCCIO. The differential pairs should be placed on adjacent pins (e.g., P and N). The clock lane should be on a dedicated clock-capable pin. The reset pin is a regular GPIO. The backlight PWM is also a regular GPIO. The PCB layout is critical: keep the MIPI traces as short as possible (less than 50 mm), and avoid vias on the differential pairs. Use a ground plane underneath the traces. The display’s connector is a 30-pin FPC with 0.5 mm pitch. The pinout includes: MIPI_D0_P, MIPI_D0_N, MIPI_D1_P, MIPI_D1_N, MIPI_CLK_P, MIPI_CLK_N, RESET, TE (tearing effect), LED_A, LED_K, VCC, GND. The TE pin is an output from the display that indicates when the frame is being updated, useful for synchronization. The FPGA can use the TE signal to avoid tearing by updating the frame buffer only during the vertical blanking. The display’s initialization sequence must be sent in MIPI command mode before switching to video mode. The FPGA can use a simple state machine to send the commands via DSI short packets. The commands are: 0x11 (sleep out), wait 120 ms, 0x36 (memory access control) with parameter 0x00 (default orientation), 0x3A (pixel format) with 0x77 (24-bit), 0xB0 (interface mode) with 0x00 (MIPI), 0x29 (display on), wait 50 ms. Then switch to video mode by sending a video mode packet. The MIPI DSI specification defines the video mode as a continuous stream of packets. The FPGA must ensure that the data is sent continuously without gaps, otherwise the display may show artifacts. The blanking intervals are filled with null packets (0x09) or low-power mode. The display’s datasheet specifies the minimum blanking time. For the ILI9488, the HBP must be at least 10 pixels, and the VBP at least 10 lines. The FPGA’s timing generator must meet these requirements. The MIPI DSI controller can be implemented in Verilog with a hierarchical design: a top module that instantiates the PLL, the MIPI TX controller, the frame buffer, and the command controller. The MIPI TX controller includes a state machine for the packet generation, a CRC generator, and a serializer. The serializer uses the OSERDESE2 primitives. The clock lane uses a differential clock output. The FPGA’s constraints file must specify the I/O standards: set the MIPI pins to LVDS_25 or MIPI_DP

A Private Word
Considering a transatlantic move?
We'd be glad to listen.
Request a Private Consultation