|
| 1 | +"""Generic ILI9xxx drivers. |
| 2 | +
|
| 3 | +This code is licensed under MIT license. |
| 4 | +
|
| 5 | +Adapted from: |
| 6 | + https://github.com/rdagger/micropython-ili9341 |
| 7 | +
|
| 8 | +The following code snippet will instantiate the driver and |
| 9 | +automatically register it to lvgl. Adjust the SPI bus and |
| 10 | +pin configurations to match your hardware setup:: |
| 11 | +
|
| 12 | + import ili9xxx |
| 13 | + from machine import SPI, Pin |
| 14 | + spi = SPI(0, baudrate=24_000_000, sck=Pin(18), mosi=Pin(19), miso=Pin(16)) |
| 15 | + drv = ili9xxx.Ili9341(spi=spi, dc=15, cs=17, rst=14) |
| 16 | +""" |
| 17 | +from micropython import const |
| 18 | + |
| 19 | +import st77xx |
| 20 | + |
| 21 | +# Command constants from ILI9341 datasheet |
| 22 | +_NOP = const(0x00) # No-op |
| 23 | +_SWRESET = const(0x01) # Software reset |
| 24 | +_RDDID = const(0x04) # Read display ID info |
| 25 | +_RDDST = const(0x09) # Read display status |
| 26 | +_SLPIN = const(0x10) # Enter sleep mode |
| 27 | +_SLPOUT = const(0x11) # Exit sleep mode |
| 28 | +_PTLON = const(0x12) # Partial mode on |
| 29 | +_NORON = const(0x13) # Normal display mode on |
| 30 | +_RDMODE = const(0x0A) # Read display power mode |
| 31 | +_RDMADCTL = const(0x0B) # Read display MADCTL |
| 32 | +_RDPIXFMT = const(0x0C) # Read display pixel format |
| 33 | +_RDIMGFMT = const(0x0D) # Read display image format |
| 34 | +_RDSELFDIAG = const(0x0F) # Read display self-diagnostic |
| 35 | +_INVOFF = const(0x20) # Display inversion off |
| 36 | +_INVON = const(0x21) # Display inversion on |
| 37 | +_GAMMASET = const(0x26) # Gamma set |
| 38 | +_DISPLAY_OFF = const(0x28) # Display off |
| 39 | +_DISPLAY_ON = const(0x29) # Display on |
| 40 | +_SET_COLUMN = const(0x2A) # Column address set |
| 41 | +_SET_PAGE = const(0x2B) # Page address set |
| 42 | +_WRITE_RAM = const(0x2C) # Memory write |
| 43 | +_READ_RAM = const(0x2E) # Memory read |
| 44 | +_PTLAR = const(0x30) # Partial area |
| 45 | +_VSCRDEF = const(0x33) # Vertical scrolling definition |
| 46 | +_MADCTL = const(0x36) # Memory access control |
| 47 | +_VSCRSADD = const(0x37) # Vertical scrolling start address |
| 48 | +_PIXFMT = const(0x3A) # COLMOD: Pixel format set |
| 49 | +_WRITE_DISPLAY_BRIGHTNESS = const(0x51) # Brightness hardware dependent! |
| 50 | +_READ_DISPLAY_BRIGHTNESS = const(0x52) |
| 51 | +_WRITE_CTRL_DISPLAY = const(0x53) |
| 52 | +_READ_CTRL_DISPLAY = const(0x54) |
| 53 | +_WRITE_CABC = const(0x55) # Write Content Adaptive Brightness Control |
| 54 | +_READ_CABC = const(0x56) # Read Content Adaptive Brightness Control |
| 55 | +_WRITE_CABC_MINIMUM = const(0x5E) # Write CABC Minimum Brightness |
| 56 | +_READ_CABC_MINIMUM = const(0x5F) # Read CABC Minimum Brightness |
| 57 | +_FRMCTR1 = const(0xB1) # Frame rate control (In normal mode/full colors) |
| 58 | +_FRMCTR2 = const(0xB2) # Frame rate control (In idle mode/8 colors) |
| 59 | +_FRMCTR3 = const(0xB3) # Frame rate control (In partial mode/full colors) |
| 60 | +_INVCTR = const(0xB4) # Display inversion control |
| 61 | +_DFUNCTR = const(0xB6) # Display function control |
| 62 | +_PWCTR1 = const(0xC0) # Power control 1 |
| 63 | +_PWCTR2 = const(0xC1) # Power control 2 |
| 64 | +_PWCTRA = const(0xCB) # Power control A |
| 65 | +_PWCTRB = const(0xCF) # Power control B |
| 66 | +_VMCTR1 = const(0xC5) # VCOM control 1 |
| 67 | +_VMCTR2 = const(0xC7) # VCOM control 2 |
| 68 | +_RDID1 = const(0xDA) # Read ID 1 |
| 69 | +_RDID2 = const(0xDB) # Read ID 2 |
| 70 | +_RDID3 = const(0xDC) # Read ID 3 |
| 71 | +_RDID4 = const(0xDD) # Read ID 4 |
| 72 | +_GMCTRP1 = const(0xE0) # Positive gamma correction |
| 73 | +_GMCTRN1 = const(0xE1) # Negative gamma correction |
| 74 | +_DTCA = const(0xE8) # Driver timing control A |
| 75 | +_DTCB = const(0xEA) # Driver timing control B |
| 76 | +_POSC = const(0xED) # Power on sequence control |
| 77 | +_ENABLE3G = const(0xF2) # Enable 3 gamma control |
| 78 | +_PUMPRC = const(0xF7) # Pump ratio control |
| 79 | + |
| 80 | +_MADCTL_MY = const(0x80) # page address order (0: top to bottom; 1: bottom to top) |
| 81 | +_MADCTL_MX = const(0x40) # column address order (0: left to right; 1: right to left) |
| 82 | +_MADCTL_MV = const(0x20) # page/column order (0: normal mode 1; reverse mode) |
| 83 | +_MADCTL_ML = const( |
| 84 | + 0x10 |
| 85 | +) # line address order (0: refresh to to bottom; 1: refresh bottom to top) |
| 86 | +_MADCTL_BGR = const(0x08) # colors are BGR (not RGB) |
| 87 | +_MADCTL_RTL = const(0x04) # refresh right to left |
| 88 | + |
| 89 | +_MADCTL_ROTS = ( |
| 90 | + const(_MADCTL_MX), # 0 = portrait |
| 91 | + const(_MADCTL_MV), # 1 = landscape |
| 92 | + const(_MADCTL_MY), # 2 = inverted portrait |
| 93 | + const(_MADCTL_MX | _MADCTL_MY | _MADCTL_MV), # 3 = inverted landscape |
| 94 | +) |
| 95 | + |
| 96 | +ILI9XXX_PORTRAIT = st77xx.ST77XX_PORTRAIT |
| 97 | +ILI9XXX_LANDSCAPE = st77xx.ST77XX_LANDSCAPE |
| 98 | +ILI9XXX_INV_PORTRAIT = st77xx.ST77XX_INV_PORTRAIT |
| 99 | +ILI9XXX_INV_LANDSCAPE = st77xx.ST77XX_INV_LANDSCAPE |
| 100 | + |
| 101 | + |
| 102 | +class Ili9341_hw(st77xx.St77xx_hw): |
| 103 | + def __init__(self, **kw): |
| 104 | + """ILI9341 TFT Display Driver. |
| 105 | +
|
| 106 | + Requires ``LV_COLOR_DEPTH=16`` when building lv_micropython to function. |
| 107 | + """ |
| 108 | + super().__init__( |
| 109 | + res=(240, 320), |
| 110 | + suppRes=[ |
| 111 | + (240, 320), |
| 112 | + ], |
| 113 | + model=None, |
| 114 | + suppModel=None, |
| 115 | + bgr=False, |
| 116 | + **kw, |
| 117 | + ) |
| 118 | + |
| 119 | + def config_hw(self): |
| 120 | + self._run_seq( |
| 121 | + [ |
| 122 | + (_SLPOUT, None, 100), |
| 123 | + (_PWCTRB, b"\x00\xC1\x30"), # Pwr ctrl B |
| 124 | + (_POSC, b"\x64\x03\x12\x81"), # Pwr on seq. ctrl |
| 125 | + (_DTCA, b"\x85\x00\x78"), # Driver timing ctrl A |
| 126 | + (_PWCTRA, b"\x39\x2C\x00\x34\x02"), # Pwr ctrl A |
| 127 | + (_PUMPRC, b"\x20"), # Pump ratio control |
| 128 | + (_DTCB, b"\x00\x00"), # Driver timing ctrl B |
| 129 | + (_PWCTR1, b"\x23"), # Pwr ctrl 1 |
| 130 | + (_PWCTR2, b"\x10"), # Pwr ctrl 2 |
| 131 | + (_VMCTR1, b"\x3E\x28"), # VCOM ctrl 1 |
| 132 | + (_VMCTR2, b"\x86"), # VCOM ctrl 2 |
| 133 | + (_VSCRSADD, b"\x00"), # Vertical scrolling start address |
| 134 | + (_PIXFMT, b"\x55"), # COLMOD: Pixel format |
| 135 | + (_FRMCTR1, b"\x00\x18"), # Frame rate ctrl |
| 136 | + (_DFUNCTR, b"\x08\x82\x27"), |
| 137 | + (_ENABLE3G, b"\x00"), # Enable 3 gamma ctrl |
| 138 | + (_GAMMASET, b"\x01"), # Gamma curve selected |
| 139 | + ( |
| 140 | + _GMCTRP1, |
| 141 | + b"\x0F\x31\x2B\x0C\x0E\x08\x4E\xF1\x37\x07\x10\x03\x0E\x09\x00", |
| 142 | + ), |
| 143 | + ( |
| 144 | + _GMCTRN1, |
| 145 | + b"\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F", |
| 146 | + ), |
| 147 | + (_SLPOUT, None, 100), |
| 148 | + (_DISPLAY_ON, None), |
| 149 | + ] |
| 150 | + ) |
| 151 | + |
| 152 | + def apply_rotation(self, rot): |
| 153 | + self.rot = rot |
| 154 | + if (self.rot % 2) == 0: |
| 155 | + self.width, self.height = self.res |
| 156 | + else: |
| 157 | + self.height, self.width = self.res |
| 158 | + self.write_register( |
| 159 | + _MADCTL, |
| 160 | + bytes([_MADCTL_BGR | _MADCTL_ROTS[self.rot % 4]]), |
| 161 | + ) |
| 162 | + |
| 163 | + |
| 164 | +class Ili9341(Ili9341_hw, st77xx.St77xx_lvgl): |
| 165 | + def __init__(self, doublebuffer=True, factor=4, **kw): |
| 166 | + """See :obj:`Ili9341_hw` for the meaning of the parameters.""" |
| 167 | + import lvgl as lv |
| 168 | + |
| 169 | + Ili9341_hw.__init__(self, **kw) |
| 170 | + st77xx.St77xx_lvgl.__init__(self, doublebuffer, factor) |
0 commit comments