1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2017-10-30 Tanek the first version
9 * 2018-04-05 Liu2guang export LCD config parameters.
10 */
11
12 #include <rtthread.h>
13
14 #ifdef BSP_USING_LCD
15
16 #include "drv_lcd.h"
17 #include "fsl_common.h"
18 #include "fsl_iomuxc.h"
19 #include "fsl_elcdif.h"
20 #include "drv_gpio.h"
21
22 #define LOG_TAG "drv.lcd"
23 #include <drv_log.h>
24
25 #if !defined(LCD_WIDTH) || !defined(LCD_HEIGHT)
26 #error "Please config lcd pixel parameters."
27 #endif
28
29 #if !defined(LCD_HFP) || !defined(LCD_HBP) || !defined(LCD_HSW) || \
30 !defined(LCD_VFP) || !defined(LCD_VBP) || !defined(LCD_VSW)
31 #error "Please config lcd timing parameters."
32 #endif
33
34 #if !defined(LCD_BL_PIN) || !defined(LCD_RST_PIN)
35 #error "Please config lcd backlight or reset pin."
36 #endif
37
38 struct imxrt_lcd
39 {
40 struct rt_device device;
41 struct rt_device_graphic_info info;
42 };
43
44 static struct imxrt_lcd lcd;
45 AT_NONCACHEABLE_SECTION_ALIGN(static uint16_t frame_buffer[LCD_HEIGHT][LCD_WIDTH], 64);
46
imxrt_lcd_init(rt_device_t device)47 static rt_err_t imxrt_lcd_init(rt_device_t device)
48 {
49 RT_ASSERT(device != RT_NULL);
50
51 rt_memset(frame_buffer, 0x00, sizeof(frame_buffer));
52 clock_video_pll_config_t pll_config;
53
54 pll_config.loopDivider = 43;
55 pll_config.postDivider = 4;
56 pll_config.numerator = 0;
57 pll_config.denominator = 0;
58
59 CLOCK_InitVideoPll(&pll_config);
60
61 rt_pin_mode(LCD_RST_PIN, PIN_MODE_OUTPUT); /* LCD_RESET */
62 rt_pin_write(LCD_RST_PIN, PIN_LOW);
63 rt_thread_delay(RT_TICK_PER_SECOND / 100);
64 rt_pin_write(LCD_RST_PIN, PIN_HIGH);
65
66 rt_pin_mode (LCD_BL_PIN, PIN_MODE_OUTPUT); /* LCD_BL */
67 rt_pin_write(LCD_BL_PIN, PIN_HIGH);
68
69 /* LCD */
70 elcdif_rgb_mode_config_t lcd_config;
71
72 lcd_config.hfp = LCD_HFP;
73 lcd_config.vfp = LCD_VFP;
74 lcd_config.hbp = LCD_HBP;
75 lcd_config.vbp = LCD_VBP;
76 lcd_config.hsw = LCD_HSW;
77 lcd_config.vsw = LCD_VSW;
78
79 lcd_config.polarityFlags = kELCDIF_DataEnableActiveHigh |
80 kELCDIF_VsyncActiveHigh |
81 kELCDIF_HsyncActiveLow |
82 kELCDIF_DriveDataOnRisingClkEdge;
83
84 lcd_config.panelWidth = LCD_WIDTH;
85 lcd_config.panelHeight = LCD_HEIGHT;
86 lcd_config.pixelFormat = kELCDIF_PixelFormatRGB565;
87 lcd_config.dataBus = kELCDIF_DataBus16Bit;
88 lcd_config.bufferAddr = (uint32_t)frame_buffer;
89
90 ELCDIF_RgbModeInit (LCDIF, &lcd_config);
91 ELCDIF_RgbModeStart(LCDIF);
92
93 /* LCD DEVICE */
94 lcd.info.width = LCD_WIDTH;
95 lcd.info.height = LCD_HEIGHT;
96 lcd.info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
97 lcd.info.bits_per_pixel = 16;
98 lcd.info.framebuffer = (void *)frame_buffer;
99
100 return RT_EOK;
101 }
102
imxrt_lcd_control(rt_device_t device,int cmd,void * args)103 static rt_err_t imxrt_lcd_control(rt_device_t device, int cmd, void *args)
104 {
105 switch(cmd)
106 {
107 case RTGRAPHIC_CTRL_RECT_UPDATE:
108 break;
109
110 case RTGRAPHIC_CTRL_POWERON:
111 rt_pin_write(LCD_BL_PIN, PIN_HIGH);
112 break;
113
114 case RTGRAPHIC_CTRL_POWEROFF:
115 rt_pin_write(LCD_BL_PIN, PIN_LOW);
116 break;
117
118 case RTGRAPHIC_CTRL_GET_INFO:
119 rt_memcpy(args, &lcd.info, sizeof(lcd.info));
120 break;
121
122 case RTGRAPHIC_CTRL_SET_MODE:
123 break;
124 }
125
126 return RT_EOK;
127 }
128
rt_hw_lcd_init(void)129 int rt_hw_lcd_init(void)
130 {
131 rt_err_t ret;
132
133 lcd.device.type = RT_Device_Class_Graphic;
134 lcd.device.init = imxrt_lcd_init;
135 lcd.device.open = RT_NULL;
136 lcd.device.close = RT_NULL;
137 lcd.device.read = RT_NULL;
138 lcd.device.write = RT_NULL;
139 lcd.device.control = imxrt_lcd_control;
140
141 lcd.device.user_data = (void *)&lcd.info;
142
143 ret = rt_device_register(&lcd.device, "lcd", RT_DEVICE_FLAG_RDWR);
144
145 return ret;
146 }
147
148 INIT_DEVICE_EXPORT(rt_hw_lcd_init);
149
150 #endif /* BSP_USING_LCD */
151