Interface details for the HY28A display with an ILI9320 controller.
Hardware
The IM[3:0] pins decide the interface mode of the controller. On the HY28A this is: 0100
According to 7.2. Input Interfaces in the datasheet, this means:
Interface mode: Serial Peripheral Interface (SPI), ID=0
The SPI interface consists of the following pins:
SCK - clock
SDI - Serial Data In, which corresponds to MOSI (Master Out Slave In)
SDO - Serial Data Out, which corresponds to MISO (Master In Slave Out)
CS - Chip Select, which corresponds to CE (Chip Enable)
SDO is not needed for driving the display, only for reading status registers etc.
SPI_MODE_3 must be used:
http://en.wikipedia.org/wiki/Serial_Per ... _and_phase
In addition to those pins we also need this:
nRESET - Hardware Reset active low
Many controllers need the reset signal to be pulsed low before operation. I haven't tried to see if just pulling it high with a 10k resistor will work (saving a gpio).
This display also has a BL_CTRL pin that controls backlight. It is tied high, so backlight is on by default. Drive this low, to turn off backlight.
See schematic for details:
http://www.haoyuelectronics.com/ebay/NX ... 8A_SCH.pdf
In SPI mode the ILI9320 needs a special start byte in each transmission. This byte contains the ID and info about the operation.
From 7.3. Serial Peripheral Interface (SPI):
Start byte[7:0]: 0 1 1 1 0 ID RS RW
ID - 0 for HY28A
RW - 0/1 - Write/read operation
RS - 0/1 - Index/data
Registers are 16-bit wide, big endian (Raspbery Pi is little endian, at least from kernel space).
GRAM - Graphics RAM
The controller contains memory (framebuffer) that is used to refresh the display. The refresh rate is set through a register.
Software
After a hardware reset the driver must initialize the registers to match the needs of the display panel. This sequence is often provided in an example code, or in the display datasheet.
Now the controller is ready to receive the pixels that will be displayed.
Before sending the pixels, the controller needs to know where in GRAM those pixels should go (set_addr_win() in FBTFT, setxy() in the UTFT library).
This is done with these three registers:
GRAM Horizontal/Vertical Address Set (R20h, R21h)
Write Data to GRAM (R22h)
Now the pixels can be sent.
To show some transfer details, I have used FBTFT with all debugging turned on:
Code: Select all
$ sudo modprobe fbtft_device name=hy28a debug=7
$ dmesg
fb_ili9320 spi0.0: set_addr_win(xs=0, ys=0
fb_ili9320 spi0.0: fbtft_write_reg16_bus8: 0020 0000
fb_ili9320 spi0.0: fbtft_write_spi(len=3): 70 00 20
fb_ili9320 spi0.0: fbtft_write_spi(len=3): 72 00 00
fb_ili9320 spi0.0: fbtft_write_reg16_bus8: 0021 0000
fb_ili9320 spi0.0: fbtft_write_spi(len=3): 70 00 21
fb_ili9320 spi0.0: fbtft_write_spi(len=3): 72 00 00
fb_ili9320 spi0.0: fbtft_write_reg16_bus8: 0022
fb_ili9320 spi0.0: fbtft_write_spi(len=3): 70 00 22
fb_ili9320 spi0.0: fbtft_write_vmem16_bus8(offset=0, len=153600)
fb_ili9320 spi0.0: fbtft_write_spi(len=4093): 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...
...
fb_ili9320 spi0.0: fbtft_write_spi(len=2197): 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...
(fbtft_write_spi() transfers a buffer over SPI. CE/CS is low during this transfer.)
First the GRAM address is set to 0,0:
Set index register 0x0020 -> 0b011100000, 0x00, 0x20
Write 0x0000 to that register -> 0b011100010, 0x00, 0x00
Set index register 0x0021 -> 0b011100000, 0x00, 0x21
Write 0x0000 to that register -> 0b011100010, 0x00, 0x00
Then GRAM write is enabled:
Set index register 0x0022 -> 0b011100000, 0x00, 0x22
Now the pixels can be sent (write_vmem), which in this example is all zeroes, turning the display black.
Since the kernel framebuffer memory has the 16-bit pixels (RGB565) stored as little endian (need to swap bytes), and a start byte has to be added to each SPI transfer, a 4k byte transfer buffer is used.
This shows how the device code is read from the controller:
Code: Select all
fb_ili9320 spi0.0: fbtft_write_reg16_bus8: 0000
fb_ili9320 spi0.0: fbtft_write_spi(len=3): 70 00 00
fb_ili9320 spi0.0: fbtft_read_spi(len=4) txbuf => 73 00 00 00
fb_ili9320 spi0.0: fbtft_read_spi(len=4) buf <= 00 93 93 20
fb_ili9320 spi0.0: Device code: 0x9320