Use the K2 LCD: Difference between revisions

From F256 Foenix
Jump to navigationJump to search
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 3: Line 3:
The LCD embedded in the enclosure is Sitronix ST7789.  
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.
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 ===
=== Registers ===
Line 22: Line 24:
|LCD_PIX_LO
|LCD_PIX_LO
|0xDD42
|0xDD42
|{G[2:0], B[4:0]}
|{G[2:0], B[4:0]} (see below in the Compatible image format section for clarity)
|-
|-
|LCD_PIX_HI
|LCD_PIX_HI
Line 29: Line 31:
|}
|}


=== Commands for LCD_CMD_CMD ===
=== Sending a command using LCD_CMD_CMD ===


{| class="wikitable"
{| class="wikitable"
|+
|+
!Command Name
!Command Name
!Address
!Value
!Description
!Description
|-
|-
Line 55: Line 57:
|LCD_WRI
|LCD_WRI
|0x2C
|0x2C
|{R[4:0], G[5:3]}
|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:<pre>
//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
</pre>Example 2, set pixel writing in reverse in the Y direction<pre>
POKE(LCD_CMD_CMD, LCD_MAD);
POKE(LCD_CMD_DTA, 0x80);
</pre>Example 3, writing pixels<pre>
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
</pre>


=== Compatible image format ===
=== Compatible image format ===
Line 70: Line 112:
The process goes as:  
The process goes as:  


1) Use gimp (or equivalent alternative) and export your image as 'Windows BMP Image', but go to advanced options
1) Use gimp (or equivalent alternative) and export your image that's using Indexed color mode as a 'Windows BMP Image'  


2) select 16 bit, R5 G6 B5 for the color  
2) During the export process, go to advanced options and select 16 bit, R5 G6 B5 for the color  


3) run my python script to convert it to a raw binary found at https://github.com/Mu0n/F256MiscGoodies/tree/main in /tools/  
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  
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 [https://github.com/Mu0n/F256KsimpleCdoodles/blob/main/lcd/src/lcd.c C github repo here], which sends an image to the LCD screen and then idles.
5) you can find some example code from my [https://github.com/Mu0n/F256KsimpleCdoodles/blob/main/lcd/src/lcd.c C github repo here], which sends an image to the LCD screen and then idles.

Latest revision as of 09:18, 11 March 2025

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.