Use the K2 LCD
The LCD is part of the F256K2 enclosure
The LCD embedded in the enclosure is Sitronix ST7789. The full resolution is 240 pixels wide, 320 pixels high. However, there's a 20 pixel high band at the top and a 20 pixel high band at the bottom which are covered, so the visible usable part is 240x280.
Its datasheet can be found in a goodies github repo: https://github.com/Mu0n/F256MiscGoodies/blob/main/datasheets/ST7789V.pdf
Registers
Register Name | Address | Description |
---|---|---|
LCD_CMD_CMD | 0xDD40 | Write Command Here |
LCD_CMD_DTA | 0xDD41 | Write Data (For Command) Here; Always Write in pairs (to LCD_PIX_LO and LCD_PIX_HI), otherwise the State Machine will Lock |
LCD_PIX_LO | 0xDD42 | {G[2:0], B[4:0]} (see below in the Compatible image format section for clarity) |
LCD_PIX_HI | 0xDD43 | {R[4:0], G[5:3]} |
Sending a command using LCD_CMD_CMD
Command Name | Value | Description |
---|---|---|
LCD_RST | 0x10 | 0 to Reset (RSTn) |
LCD_BL | 0x20 | 1 = ON, 0 = OFF |
LCD_WIN_X | 0x2A | define window X |
LCD_WIN_Y | 0x2B | define window Y |
LCD_WRI | 0x2C | put in memory write mode (pixel writing) |
LCD_RD | 0x2E | put in memory read mode |
LCD_MAD | 0x36 | MADCTL register, which controls in which direction pixel writing occurs |
LCD_TE | 0x40 | Enable tear mode - avoid updating the display while the controller reads its value |
The process for sending a command goes as:
1) send the appropriate command byte to LCD_CMD_CMD
2) write all of your appropriate data byte, in the correct sequence according to the documentation, to LCD_CMD_DTA
Example 1, setting a rectangular region on the LCD to receive pixel writes and managing how 'pixel write carriage returns' behave:
//assuming an 8-bit value x and width and a 16-bit value y and height POKE(LCD_CMD_CMD, LCD_WIN_X); POKE(LCD_CMD_DTA, 0); //xstart high, this will always be 0 since the width is 240 pixels wide POKE(LCD_CMD_DTA, x); //xstart low POKE(LCD_CMD_DTA, 0); //xend high POKE(LCD_CMD_DTA, x+width); //xend low POKE(LCD_CMD_CMD, LCD_WIN_Y); POKE(LCD_CMD_DTA, (y&0xFF00)); //ystart high POKE(LCD_CMD_DTA, 20 + (y&0x00FF)); //ystart low POKE(LCD_CMD_DTA, (y+height)&0x00FF); //yend high POKE(LCD_CMD_DTA, (y+height)&0x00FF); //yend low
Example 2, set pixel writing in reverse in the Y direction
POKE(LCD_CMD_CMD, LCD_MAD); POKE(LCD_CMD_DTA, 0x80);
Example 3, writing pixels
POKE(LCD_CMD_CMD, LCD_WRI); //only set this once at the start of writing pixel data and redo it if you needed to get sidetracked and did other types of commands //start of your loop POKEW(LCD_PIX_LO,PIXEL_IN_R5G6B5); //send a word at once //end of your loop, only the pixels declared in the rectangular region from example 1 will be affected
Compatible image format
You can send in a .bmp image exported in R5 G6 B5 color palette, converted into a raw 2 byte/per/pixel binary file. The R5 G6 B5 palette expects color information in this format:
High byte__ Low byte
RRRRRGGG GGGBBBBBB
The process goes as:
1) Use gimp (or equivalent alternative) and export your image that's using Indexed color mode as a 'Windows BMP Image'
2) During the export process, go to advanced options and select 16 bit, R5 G6 B5 for the color
3) run my python script 'bmp2LCD.py' to convert it to a raw binary found at https://github.com/Mu0n/F256MiscGoodies/tree/main in /tools/
4) for every pixel, send 2 bytes of data to the LCD_PIX_LO and LCD_PIX_HI registers found in the table above
5) you can find some example code from my C github repo here, which sends an image to the LCD screen and then idles.