Skip to content

Latest commit

 

History

History
125 lines (99 loc) · 5.59 KB

ili9341.md

File metadata and controls

125 lines (99 loc) · 5.59 KB

ILI9341 display driver

Copyright 2020 Moddable Tech, Inc.
Revised: September 10, 2024

The ILI9341 LCD controller drives 16-bits per pixel (RGB565LE) displays. Displays are up to 240 pixels wide and 320 pixels high.

The ILI9341 driver has been successfully used with the ILI9163C display controller with a 128 x 128 pixel square display at 16-bits per pixel.

Adding ILI9341 to a project

To add the ILI9341 driver to a project, include its manifest:

"include": [
	/* other includes here */
	"$(MODULES)/drivers/ili9341/manifest.json"
],

If using Commodetto or Piu, set the screen property of the config object in the manifest to ili9341 to make ILI9341 the default display driver. If there is no touch input, set the touch driver name to an empty string to disable it.

"config": {
	"screen": "ili9341",
	"touch": ""
},

Note: The manifest_piu.json manifest includes ILI9341. Therefore, projects using manifest_piu.json do not need to include it themselves.

Pixel formats

The ILI9341 driver supports many different pixel formats as input. 16-bit color pixels are the native format of the driver, and so are most commonly used. When building with mcconfig, set the pixel format to rgb565le on the command line:

mcconfig -m -p esp -f rgb565le

Other formats supported directly by the ILI9341 driver are 8-bit gray (gray256), 8-bit color (rgb332), and 4-bit gray (gray16).

In addition, 4-bit color (clut16) is also supported. There is no default color table; the application must set the color table. Using Poco, the color table is passed as the clut property in the dictionary of the constructor. Using Piu, the color table is automatically loaded from a Resource named main.cct. It may also be set explicitly on the application's clut property. See the PIU clut example for a working example of changing the color table from a script.

While most projects will use the 16-bit RGB pixels, the other pixel formats are useful:

  • to test how an applications renders on display with lower color resolutions
  • to reduce the size of color image resources in ROM
  • to reduce RAM use (smaller size pixels use smaller a smaller rendering buffer, e.g. a 4-bit gray pixel 75% less RAM than a 16-bit RGB pixel)

Defines

In the defines object, declare the pixel width and height.

"defines": {
	"ili9341": {
		"width": 128,
		"height": 128
	}
}

The optional registers property is used to override the default initialization of registers on the ILI9341. The register property is compiled in C as part of the driver source code, so it has access to the same #define constants as the driver, hence the use of kDelayMS, MODDEF_ILI9341_FLIPY, and MODDEF_ILI9341_FLIPX below. The list of register commands is terminated with pseudo-registers kDelayMS with a value of 0.

"defines": {
	"ili9341": {
		/* other properties here */
		"registers": [
			"0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,",
			"0xCF, 3, 0x00, 0xC1, 0X30,",
			"0xE8, 3, 0x85, 0x00, 0x78,",
			"0xEA, 2, 0x00, 0x00,",
			"0xED, 4, 0x64, 0x03, 0x12, 0x81,",
			"0xF7, 1, 0x20,",
			"0xC0, 1, 0x23,",
			"0xC1, 1, 0x10,",
			"0xC5, 2, 0x3e, 0x28,",
			"0xC7, 1, 0x86,",
			"0x36, 1, (0x48 ^ (MODDEF_ILI9341_FLIPY ? 0x80 : 0)) ^ (MODDEF_ILI9341_FLIPX ? 0x40 : 0),",
			"0x3A, 1, 0x55,",
			"0xB1, 2, 0x00, 0x18,",
			"0xB6, 3, 0x08, 0x82, 0x27,",
			"0xF2, 1, 0x00,",
			"0x26, 1, 0x01,",
			"0xE0, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,",
			"0xE1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,",
			"0x11, 0,",
			"0x29, 0,",
			"kDelayMS, 0"
		]
	}
}

Configuring SPI

The defines object must contain the spi_port, along with the DC and CS pin numbers. If a RST pin is provided, the device will be reset when the constructor is invoked. If the cs_port, dc_port, or rst_port properties are not provided, they default to NULL.

"defines": {
	"ili9341": {
		/* other properties here */
		"cs_pin": 4,
		"dc_pin": 2,
		"rst_pin": 0,
		"spi_port": "#HSPI"
	}
}

The hz property, when present, specifies the SPI bus speed. The default value is 40,000,000 Hz which is near the maximum SPI speed supported by the ILI9341.

Async

The ILI9341 driver implements asynchronous SPI transactions to optimize throughput and minimize CPU time required during transmission. To avoid requiring extra RAM to store the pixels being transmitted, the ILI9341 driver transmits directly from the buffers provided by the script. This means that the buffer provided the ILI9341 send call must remain unchanged until the next call to send, continue or end returns.

Using Poco or Piu, to enable asynchronous operation of ILI9341, the number of pixels in the render buffer must be two full scan lines or more. This is the default so scripts only need to consider this if they are calling the ILI9341 constructor directly. To set the number of pixels in the render buffer, set the pixels property to the number of pixels in the dictionary passed to the ILI9341 constructor.

Command API

The ILI9341 driver extends the PixelsOut interface with a command method to allow scripts to issue commands directly to the display controller. To send a command with no data arguments:

// invert on
screen.command(0x21);

To send a command with data arguments, put the arguments into an ArrayBuffer:

// rotate 90
screen.command(0x36, Uint8Array.of(0x60).buffer);