1 /*
2 * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-02-25 lik first version
9 */
10
11 #include "drv_rgb_lcd.h"
12
13 #ifdef BSP_USING_RGB_LCD
14 #include "rgb_lcd_port.h"
15
16 #define DRV_DEBUG
17 #define LOG_TAG "drv.rgb_lcd"
18 #include <drv_log.h>
19
20 #define LCD_DEVICE(dev) (struct swm_rgb_lcd_device *)(dev)
21
22 struct swm_rgb_lcd_device rgb_lcd_obj;
23
swm_rgb_lcd_configure(struct rt_device * device)24 static rt_err_t swm_rgb_lcd_configure(struct rt_device *device)
25 {
26 struct swm_rgb_lcd_device *rgb_lcd = LCD_DEVICE(device);
27 /* nothing, right now */
28 rgb_lcd = rgb_lcd;
29 return RT_EOK;
30 }
31
swm_rgb_lcd_control(struct rt_device * device,int cmd,void * args)32 static rt_err_t swm_rgb_lcd_control(struct rt_device *device, int cmd, void *args)
33 {
34 struct swm_rgb_lcd_device *rgb_lcd = LCD_DEVICE(device);
35
36 switch (cmd)
37 {
38 case RTGRAPHIC_CTRL_GET_INFO:
39 {
40 struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args;
41
42 RT_ASSERT(info != RT_NULL);
43 info->pixel_format = rgb_lcd->lcd_info.pixel_format;
44 info->bits_per_pixel = rgb_lcd->lcd_info.bits_per_pixel;
45 info->width = rgb_lcd->lcd_info.width;
46 info->height = rgb_lcd->lcd_info.height;
47 info->framebuffer = rgb_lcd->lcd_info.framebuffer;
48 }
49 break;
50
51 default:
52 return -RT_EINVAL;
53 }
54
55 return RT_EOK;
56 }
57
58 #if defined(LCD_BACKLIGHT_USING_PWM)
turn_on_lcd_backlight(void)59 static void turn_on_lcd_backlight(void)
60 {
61 struct rt_device_pwm *pwm_dev;
62
63 /* turn on the LCD backlight */
64 pwm_dev = (struct rt_device_pwm *)rt_device_find(LCD_PWM_DEV_NAME);
65 /* pwm frequency:100K = 10000ns */
66 rt_pwm_set(pwm_dev, LCD_PWM_DEV_CHANNEL, 10000, 10000);
67 rt_pwm_enable(pwm_dev, LCD_PWM_DEV_CHANNEL);
68 }
69 #elif defined(LCD_BACKLIGHT_USING_GPIO)
turn_on_lcd_backlight(void)70 static void turn_on_lcd_backlight(void)
71 {
72 rt_pin_mode(LCD_DISP_GPIO, PIN_MODE_OUTPUT);
73 rt_pin_write(LCD_DISP_GPIO, PIN_HIGH);
74
75 rt_pin_mode(LCD_BL_GPIO, PIN_MODE_OUTPUT);
76 rt_pin_write(LCD_BL_GPIO, PIN_HIGH);
77 }
78 #else
turn_on_lcd_backlight(void)79 static void turn_on_lcd_backlight(void)
80 {
81 }
82 #endif
83
84 #ifdef RT_USING_DEVICE_OPS
85 static const struct rt_device_ops swm_lcd_ops =
86 {
87 .init = swm_rgb_lcd_configure,
88 .open = RT_NULL,
89 .close = RT_NULL,
90 .read = RT_NULL,
91 .write = RT_NULL,
92 .control = swm_rgb_lcd_control};
93 #endif
94
swm_rgb_lcd_init(void)95 int swm_rgb_lcd_init(void)
96 {
97 rt_err_t result = RT_EOK;
98 struct rt_device *device = &rgb_lcd_obj.parent;
99
100 /* memset rgb_lcd_obj to zero */
101 memset(&rgb_lcd_obj, 0x00, sizeof(rgb_lcd_obj));
102
103 /* config LCD dev info */
104 rgb_lcd_obj.lcd_info.height = LCD_HEIGHT;
105 rgb_lcd_obj.lcd_info.width = LCD_WIDTH;
106 rgb_lcd_obj.lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL;
107 rgb_lcd_obj.lcd_info.pixel_format = LCD_PIXEL_FORMAT;
108
109 /* malloc memory for Triple Buffering */
110 rgb_lcd_obj.lcd_info.framebuffer = rt_malloc_align(LCD_BUF_SIZE,4);
111 if (rgb_lcd_obj.lcd_info.framebuffer == RT_NULL)
112 {
113 LOG_E("init frame buffer failed!\n");
114 result = -RT_ENOMEM;
115 goto __exit;
116 }
117 /* memset buff to 0xFF */
118 memset(rgb_lcd_obj.lcd_info.framebuffer, 0xFF, LCD_BUF_SIZE);
119
120 device->type = RT_Device_Class_Graphic;
121 #ifdef RT_USING_DEVICE_OPS
122 device->ops = &swm_lcd_ops;
123 #else
124 device->init = swm_rgb_lcd_configure;
125 device->control = swm_rgb_lcd_control;
126 #endif
127 /* register lcd device */
128 rt_device_register(device, "rgb_lcd", RT_DEVICE_FLAG_RDWR);
129
130 LCD_InitStructure LCD_initStruct;
131
132 // PORT_Init(PORTB, PIN1, PORTB_PIN1_LCD_B0, 0);
133 // PORT_Init(PORTB, PIN11, PORTB_PIN11_LCD_B1, 0);
134 // PORT_Init(PORTB, PIN13, PORTB_PIN13_LCD_B2, 0);
135 PORT_Init(PORTB, PIN15, PORTB_PIN15_LCD_B3, 0);
136 PORT_Init(PORTA, PIN2, PORTA_PIN2_LCD_B4, 0);
137 PORT_Init(PORTA, PIN9, PORTA_PIN9_LCD_B5, 0);
138 PORT_Init(PORTA, PIN10, PORTA_PIN10_LCD_B6, 0);
139 PORT_Init(PORTA, PIN11, PORTA_PIN11_LCD_B7, 0);
140
141 // PORT_Init(PORTA, PIN12, PORTA_PIN12_LCD_G0, 0);
142 // PORT_Init(PORTA, PIN13, PORTA_PIN13_LCD_G1, 0);
143 PORT_Init(PORTA, PIN14, PORTA_PIN14_LCD_G2, 0);
144 PORT_Init(PORTA, PIN15, PORTA_PIN15_LCD_G3, 0);
145 PORT_Init(PORTC, PIN0, PORTC_PIN0_LCD_G4, 0);
146 PORT_Init(PORTC, PIN1, PORTC_PIN1_LCD_G5, 0);
147 PORT_Init(PORTC, PIN2, PORTC_PIN2_LCD_G6, 0);
148 PORT_Init(PORTC, PIN3, PORTC_PIN3_LCD_G7, 0);
149
150 // PORT_Init(PORTC, PIN4, PORTC_PIN4_LCD_R0, 0);
151 // PORT_Init(PORTC, PIN5, PORTC_PIN5_LCD_R1, 0);
152 // PORT_Init(PORTC, PIN8, PORTC_PIN8_LCD_R2, 0);
153 PORT_Init(PORTC, PIN9, PORTC_PIN9_LCD_R3, 0);
154 PORT_Init(PORTC, PIN10, PORTC_PIN10_LCD_R4, 0);
155 PORT_Init(PORTC, PIN11, PORTC_PIN11_LCD_R5, 0);
156 PORT_Init(PORTC, PIN12, PORTC_PIN12_LCD_R6, 0);
157 PORT_Init(PORTC, PIN13, PORTC_PIN13_LCD_R7, 0);
158
159 PORT_Init(PORTB, PIN2, PORTB_PIN2_LCD_VSYNC, 0);
160 PORT_Init(PORTB, PIN3, PORTB_PIN3_LCD_HSYNC, 0);
161 PORT_Init(PORTB, PIN4, PORTB_PIN4_LCD_DEN, 0);
162 PORT_Init(PORTB, PIN5, PORTB_PIN5_LCD_DCLK, 0);
163
164 LCD_initStruct.ClkDiv = LCD_CLK_DIV;
165 LCD_initStruct.Format = ((LCD_BITS_PER_PIXEL == 16) ? LCD_FMT_RGB565 : LCD_FMT_RGB888);
166 LCD_initStruct.HnPixel = LCD_WIDTH;
167 LCD_initStruct.VnPixel = LCD_HEIGHT;
168 LCD_initStruct.Hfp = LCD_HFP;
169 LCD_initStruct.Hbp = LCD_HBP;
170 LCD_initStruct.Vfp = LCD_VFP;
171 LCD_initStruct.Vbp = LCD_VBP;
172 LCD_initStruct.HsyncWidth = LCD_HSYNC_WIDTH;
173 LCD_initStruct.VsyncWidth = LCD_VSYNC_WIDTH;
174
175 LCD_initStruct.DataSource = (uint32_t)rgb_lcd_obj.lcd_info.framebuffer;
176 LCD_initStruct.Background = 0xFFFFFF;
177 LCD_initStruct.SampleEdge = LCD_SAMPLE_FALL;
178 LCD_initStruct.IntEOTEn = 0;
179 LCD_Init(LCD, &LCD_initStruct);
180 LCD_Start(LCD);
181 turn_on_lcd_backlight();
182 __exit:
183 if (result != RT_EOK)
184 {
185 if (rgb_lcd_obj.lcd_info.framebuffer)
186 {
187 rt_free(rgb_lcd_obj.lcd_info.framebuffer);
188 }
189 }
190 return result;
191 }
192 INIT_BOARD_EXPORT(swm_rgb_lcd_init);
193
lcd_test(void)194 int lcd_test(void)
195 {
196 struct swm_rgb_lcd_device *rgb_lcd;
197 rgb_lcd = (struct swm_rgb_lcd_device *)rt_device_find("rgb_lcd");
198
199 // while (1)
200 {
201 /* red */
202 for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
203 {
204 rgb_lcd->lcd_info.framebuffer[2 * i] = 0x00;
205 rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0xF8;
206 }
207 rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
208 rt_thread_mdelay(1000);
209 /* green */
210 for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
211 {
212 rgb_lcd->lcd_info.framebuffer[2 * i] = 0xE0;
213 rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0x07;
214 }
215 rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
216 rt_thread_mdelay(1000);
217 /* blue */
218 for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
219 {
220 rgb_lcd->lcd_info.framebuffer[2 * i] = 0x1F;
221 rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0x00;
222 }
223 rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
224 rt_thread_mdelay(1000);
225 }
226 return 0;
227 }
228 MSH_CMD_EXPORT(lcd_test, lcd_test);
229
230 #endif /* BSP_USING_RGB_LCD */
231