1 /**
2  * @file lv_lcd_generic_mipi.h
3  *
4  * Generic driver for controllers adhering to the MIPI DBI/DCS specification
5  *
6  * Works with:
7  *
8  * ST7735
9  * ST7789
10  * ST7796
11  * ILI9341
12  * ILI9488 (NOTE: in SPI mode ILI9488 only supports RGB666 mode, which is currently not supported)
13  *
14  * any probably many more
15  *
16  */
17 
18 #ifndef LV_LCD_GENERIC_MIPI_H
19 #define LV_LCD_GENERIC_MIPI_H
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /*********************
26  *      INCLUDES
27  *********************/
28 
29 #include "../../../display/lv_display.h"
30 
31 #if LV_USE_GENERIC_MIPI
32 
33 /*********************
34  *      DEFINES
35  *********************/
36 
37 /* MIPI DCS (Display Command Set) v1.02.00 User Command Set */
38 #define LV_LCD_CMD_NOP                      0x00    /* No Operation */
39 #define LV_LCD_CMD_SOFT_RESET               0x01    /* Software Reset */
40 #define LV_LCD_CMD_GET_POWER_MODE           0x0A    /* Get the current power mode */
41 #define LV_LCD_CMD_GET_ADDRESS_MODE         0x0B    /* Get the data order for transfers from the Host to the display module and from the frame memory to the display device */
42 #define LV_LCD_CMD_GET_PIXEL_FORMAT         0x0C    /* Get the current pixel format */
43 #define LV_LCD_CMD_GET_DISPLAY_MODE         0x0D    /* Get the current display mode from the peripheral */
44 #define LV_LCD_CMD_GET_SIGNAL_MODE          0x0E    /* Get display module signaling mode */
45 #define LV_LCD_CMD_GET_DIAGNOSTIC_RESULT    0x0F    /* Get Peripheral Self-Diagnostic Result */
46 #define LV_LCD_CMD_ENTER_SLEEP_MODE         0x10    /* Power for the display panel is off */
47 #define LV_LCD_CMD_EXIT_SLEEP_MODE          0x11    /* Power for the display panel is on */
48 #define LV_LCD_CMD_ENTER_PARTIAL_MODE       0x12    /* Part of the display area is used for image display */
49 #define LV_LCD_CMD_ENTER_NORMAL_MODE        0x13    /* The whole display area is used for image display */
50 #define LV_LCD_CMD_EXIT_INVERT_MODE         0x20    /* Displayed image colors are not inverted */
51 #define LV_LCD_CMD_ENTER_INVERT_MODE        0x21    /* Displayed image colors are inverted */
52 #define LV_LCD_CMD_SET_GAMMA_CURVE          0x26    /* Selects the gamma curve used by the display device */
53 #define LV_LCD_CMD_SET_DISPLAY_OFF          0x28    /* Blanks the display device */
54 #define LV_LCD_CMD_SET_DISPLAY_ON           0x29    /* Show the image on the display device */
55 #define LV_LCD_CMD_SET_COLUMN_ADDRESS       0x2A    /* Set the column extent */
56 #define LV_LCD_CMD_SET_PAGE_ADDRESS         0x2B    /* Set the page extent */
57 #define LV_LCD_CMD_WRITE_MEMORY_START       0x2C    /* Transfer image data from the Host Processor to the peripheral starting at the location provided by set_column_address and set_page_address */
58 #define LV_LCD_CMD_READ_MEMORY_START        0x2E    /* Transfer image data from the peripheral to the Host Processor interface starting at the location provided by set_column_address and set_page_address */
59 #define LV_LCD_CMD_SET_PARTIAL_ROWS         0x30    /* Defines the number of rows in the partial display area on the display device */
60 #define LV_LCD_CMD_SET_PARTIAL_COLUMNS      0x31    /* Defines the number of columns in the partial display area on the display device */
61 #define LV_LCD_CMD_SET_SCROLL_AREA          0x33    /* Defines the vertical scrolling and fixed area on display device */
62 #define LV_LCD_CMD_SET_TEAR_OFF             0x34    /* Synchronization information is not sent from the display module to the host processor */
63 #define LV_LCD_CMD_SET_TEAR_ON              0x35    /* Synchronization information is sent from the display module to the host processor at the start of VFP */
64 #define LV_LCD_CMD_SET_ADDRESS_MODE         0x36    /* Set the data order for transfers from the Host to the display module and from the frame memory to the display device */
65 #define LV_LCD_CMD_SET_SCROLL_START         0x37    /* Defines the vertical scrolling starting point */
66 #define LV_LCD_CMD_EXIT_IDLE_MODE           0x38    /* Full color depth is used on the display panel */
67 #define LV_LCD_CMD_ENTER_IDLE_MODE          0x39    /* Reduced color depth is used on the display panel */
68 #define LV_LCD_CMD_SET_PIXEL_FORMAT         0x3A    /* Defines how many bits per pixel are used in the interface */
69 #define LV_LCD_CMD_WRITE_MEMORY_CONTINUE    0x3C    /* Transfer image information from the Host Processor interface to the peripheral from the last written location */
70 #define LV_LCD_CMD_READ_MEMORY_CONTINUE     0x3E    /* Read image data from the peripheral continuing after the last read_memory_continue or read_memory_start */
71 #define LV_LCD_CMD_SET_TEAR_SCANLINE        0x44    /* Synchronization information is sent from the display module to the host processor when the display device refresh reaches the provided scanline */
72 #define LV_LCD_CMD_GET_SCANLINE             0x45    /* Get the current scanline */
73 #define LV_LCD_CMD_READ_DDB_CONTINUE        0xA8    /* Continue reading the DDB from the last read location */
74 #define LV_LCD_CMD_READ_DDB_START           0xA1    /* Read the DDB from the provided location */
75 
76 /* address mode flag masks */
77 #define LV_LCD_MASK_FLIP_VERTICAL                       (1 << 0)    /* This bit flips the image shown on the display device top to bottom. No change is made to the frame memory */
78 #define LV_LCD_MASK_FLIP_HORIZONTAL                     (1 << 1)    /* This bit flips the image shown on the display device left to right. No change is made to the frame memory */
79 #define LV_LCD_MASK_DATA_LATCH_DATA_ORDER               (1 << 2)    /* Display Data Latch Order */
80 #define LV_LCD_MASK_RGB_ORDER                           (1 << 3)    /* RGB/BGR Order */
81 #define LV_LCD_MASK_LINE_ADDRESS_ORDER                  (1 << 4)    /* Line Address Order */
82 #define LV_LCD_MASK_PAGE_COLUMN_ORDER                   (1 << 5)    /* Page/Column Order */
83 #define LV_LCD_MASK_COLUMN_ADDRESS_ORDER                (1 << 6)    /* Column Address Order */
84 #define LV_LCD_MASK_PAGE_ADDRESS_ORDER                  (1 << 7)    /* Page Address Order */
85 
86 #define LV_LCD_BIT_FLIP_VERTICAL__NOT_FLIPPED           0
87 #define LV_LCD_BIT_FLIP_VERTICAL__FLIPPED               LV_LCD_MASK_FLIP_VERTICAL           /* This bit flips the image shown on the display device top to bottom. No change is made to the frame memory */
88 #define LV_LCD_BIT_FLIP_HORIZONTAL__NOT_FLIPPED         0
89 #define LV_LCD_BIT_FLIP_HORIZONTAL__FLIPPED             LV_LCD_MASK_FLIP_HORIZONTAL         /* This bit flips the image shown on the display device left to right. No change is made to the frame memory */
90 #define LV_LCD_BIT_DATA_LATCH_DATA_ORDER__LTOR          0                                   /* Display Data Latch Order: LCD Refresh Left to Right */
91 #define LV_LCD_BIT_DATA_LATCH_DATA_ORDER__RTOL          LV_LCD_MASK_DATA_LATCH_DATA_ORDER   /* Display Data Latch Order: LCD Refresh Right to Left */
92 #define LV_LCD_BIT_RGB_ORDER__RGB                       0                                   /* RGB/BGR Order: RGB */
93 #define LV_LCD_BIT_RGB_ORDER__BGR                       LV_LCD_MASK_RGB_ORDER               /* RGB/BGR Order: BGR */
94 #define LV_LCD_BIT_LINE_ADDRESS_ORDER__TTOB             0                                   /* Line Address Order: LCD Refresh Top to Bottom */
95 #define LV_LCD_BIT_LINE_ADDRESS_ORDER__BTOT             LV_LCD_MASK_LINE_ADDRESS_ORDER      /* Line Address Order: LCD Refresh Bottom to Top */
96 #define LV_LCD_BIT_PAGE_COLUMN_ORDER__NORMAL            0                                   /* Page/Column Order: Normal Mode */
97 #define LV_LCD_BIT_PAGE_COLUMN_ORDER__REVERSE           LV_LCD_MASK_PAGE_COLUMN_ORDER       /* Page/Column Order: Reverse Mode */
98 #define LV_LCD_BIT_COLUMN_ADDRESS_ORDER__LTOR           0                                   /* Column Address Order: Left to Right */
99 #define LV_LCD_BIT_COLUMN_ADDRESS_ORDER__RTOL           LV_LCD_MASK_COLUMN_ADDRESS_ORDER    /* Column Address Order: Right to Left */
100 #define LV_LCD_BIT_PAGE_ADDRESS_ORDER__TTOB             0                                   /* Page Address Order: Top to Bottom */
101 #define LV_LCD_BIT_PAGE_ADDRESS_ORDER__BTOT             LV_LCD_MASK_PAGE_ADDRESS_ORDER      /* Page Address Order: Bottom to Top */
102 
103 /* predefined gamma curves */
104 #define LV_LCD_GAMMA_2_2                                0x01    /* 2.2 */
105 #define LV_LCD_GAMMA_1_8                                0x02    /* 1.8 */
106 #define LV_LCD_GAMMA_2_5                                0x04    /* 2.5 */
107 #define LV_LCD_GAMMA_1_0                                0x08    /* 1.0 */
108 
109 /* common pixel formats */
110 #define LV_LCD_PIXEL_FORMAT_RGB565                      0x55    /* bus: 16 bits, pixel: 16 bits */
111 #define LV_LCD_PIXEL_FORMAT_RGB666                      0x66    /* bus: 18 bits, pixel: 18 bits */
112 
113 /* flags for lv_lcd_xxx_create() */
114 #define LV_LCD_FLAG_NONE                                0x00000000UL
115 #define LV_LCD_FLAG_MIRROR_X                            0x00000001UL
116 #define LV_LCD_FLAG_MIRROR_Y                            0x00000002UL
117 #define LV_LCD_FLAG_BGR                                 0x00000008UL
118 #define LV_LCD_FLAG_RGB666                              0x00000010UL
119 
120 /* command list */
121 #define LV_LCD_CMD_DELAY_MS     0xff
122 #define LV_LCD_CMD_EOF          0xff
123 
124 /**********************
125  *      TYPEDEFS
126  **********************/
127 
128 /**
129  *  Configuration flags for lv_lcd_xxx_create()
130  *
131  */
132 typedef uint32_t lv_lcd_flag_t;
133 
134 /**
135  * Prototype of a platform-dependent callback to transfer commands and data to the LCD controller.
136  * @param disp          display object
137  * @param cmd           command buffer (can handle 16 bit commands as well)
138  * @param cmd_size      number of bytes of the command
139  * @param param         parameter buffer
140  * @param param_size    number of bytes of the parameters
141  */
142 typedef void (*lv_lcd_send_cmd_cb_t)(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, const uint8_t * param,
143                                      size_t param_size);
144 
145 /**
146  * Prototype of a platform-dependent callback to transfer pixel data to the LCD controller.
147  * @param disp          display object
148  * @param cmd           command buffer (can handle 16 bit commands as well)
149  * @param cmd_size      number of bytes of the command
150  * @param param         parameter buffer
151  * @param param_size    number of bytes of the parameters
152  */
153 typedef void (*lv_lcd_send_color_cb_t)(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, uint8_t * param,
154                                        size_t param_size);
155 
156 /**
157  * Generic MIPI compatible LCD driver
158  */
159 typedef struct {
160     lv_display_t      *     disp;          /* the associated LVGL display object */
161     lv_lcd_send_cmd_cb_t    send_cmd;       /* platform-specific implementation to send a command to the LCD controller */
162     lv_lcd_send_color_cb_t  send_color;     /* platform-specific implementation to send pixel data to the LCD controller */
163     uint16_t                x_gap;          /* x offset of the (0,0) pixel in VRAM */
164     uint16_t                y_gap;          /* y offset of the (0,0) pixel in VRAM */
165     uint8_t                 madctl_reg;     /* current value of MADCTL register */
166     uint8_t                 colmod_reg;     /* current value of COLMOD register */
167     bool                    mirror_x;
168     bool                    mirror_y;
169     bool                    swap_xy;
170 } lv_lcd_generic_mipi_driver_t;
171 
172 /**********************
173  *  GLOBAL PROTOTYPES
174  **********************/
175 
176 /**
177  * Create a MIPI DCS compatible LCD display
178  * @param hor_res       horizontal resolution
179  * @param ver_res       vertical resolution
180  * @param flags         default configuration settings (mirror, RGB ordering, etc.)
181  * @param send_cmd      platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
182  * @param send_color    platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
183  * @return              pointer to the created display
184  */
185 lv_display_t * lv_lcd_generic_mipi_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
186                                           lv_lcd_send_cmd_cb_t send_cmd_cb, lv_lcd_send_color_cb_t send_color_cb);
187 
188 /**
189  * Set gap, i.e., the offset of the (0,0) pixel in the VRAM
190  * @param disp          display object
191  * @param x             x offset
192  * @param y             y offset
193  */
194 void lv_lcd_generic_mipi_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
195 
196 /**
197  * Set color inversion
198  * @param disp          display object
199  * @param invert        false: normal, true: invert
200  */
201 void lv_lcd_generic_mipi_set_invert(lv_display_t * disp, bool invert);
202 
203 /**
204  * Set address mode
205  * @param disp          display object
206  * @param mirror_x      horizontal mirror (false: normal, true: mirrored)
207  * @param mirror_y      vertical mirror (false: normal, true: mirrored)
208  * @param swap_xy       swap axes (false: normal, true: swap)
209  * @param bgr           RGB/BGR order (false: RGB, true: BGR)
210  */
211 void lv_lcd_generic_mipi_set_address_mode(lv_display_t * disp, bool mirror_x, bool mirror_y, bool swap_xy, bool bgr);
212 
213 /**
214  * Set gamma curve
215  * @param disp          display object
216  * @param gamma         gamma curve
217  */
218 void lv_lcd_generic_mipi_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
219 
220 /**
221  * Send list of commands.
222  * @param disp          display object
223  * @param cmd_list      controller and panel-specific commands
224  */
225 void lv_lcd_generic_mipi_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
226 
227 /**********************
228  *      OTHERS
229  **********************/
230 
231 /**********************
232  *      MACROS
233  **********************/
234 
235 
236 #endif /*LV_USE_GENERIC_MIPI*/
237 
238 #ifdef __cplusplus
239 } /*extern "C"*/
240 #endif
241 
242 #endif /*LV_LCD_GENERIC_MIPI_H*/
243