embox

Форк
0
/
stm32cube_lcd.c 
269 строк · 6.3 Кб
1
/**
2
 * @file
3
 * @brief
4
 *
5
 * @date 16.07.15
6
 * @author
7
 */
8

9
#include <errno.h>
10
#include <assert.h>
11
#include <stdint.h>
12
#include <string.h>
13
#include <sys/mman.h>
14

15
#include <drivers/video/fb.h>
16
#include <mem/page.h>
17
#include <util/binalign.h>
18
#include <util/log.h>
19
#include <kernel/irq.h>
20

21
#if defined STM32F746xx
22
#include "stm32746g_discovery_lcd.h"
23
#elif defined STM32F769xx
24
#include "stm32f769i_discovery_lcd.h"
25
#elif defined STM32H745xx
26
#include "stm32h745i_discovery_lcd.h"
27
#else
28
#error Unsupported platform
29
#endif
30

31
/* Initialize layer 0 as active for all F7 boards. */
32
#undef LTDC_ACTIVE_LAYER
33
#define LTDC_ACTIVE_LAYER 0
34

35
#include <embox/unit.h>
36
EMBOX_UNIT_INIT(stm32cube_lcd_init);
37

38
#define LTDC_IRQ      OPTION_GET(NUMBER,ltdc_irq)
39
static_assert(LTDC_IRQ == LTDC_IRQn, "");
40

41
#define USE_FB_SECTION OPTION_GET(BOOLEAN,use_fb_section)
42

43
#if USE_FB_SECTION
44
#define STM32_FB_SECTION_START OPTION_GET(STRING,fb_section_start)
45
extern char STM32_FB_SECTION_START;
46
#else
47
#define STM32_FB_START  OPTION_GET(NUMBER, fb_base)
48
#endif
49

50
#define STM32_LCD_HEIGHT  OPTION_GET(NUMBER, height)
51
#define STM32_LCD_WIDTH   OPTION_GET(NUMBER, width)
52
#define STM32_LCD_BPP     OPTION_GET(NUMBER, bpp)
53

54
#if defined STM32F746xx
55
extern LTDC_HandleTypeDef hLtdcHandler;
56
#define hltdc_handler hLtdcHandler
57
#elif defined STM32F769xx
58
extern LTDC_HandleTypeDef  hltdc_discovery;
59
#define hltdc_handler hltdc_discovery
60
#elif defined STM32H745xx
61
extern LTDC_HandleTypeDef hlcd_ltdc;
62
#define hltdc_handler hlcd_ltdc
63
#else
64
#error Unsupported platform
65
#endif
66

67
static int stm32cube_lcd_set_var(struct fb_info *info,
68
		struct fb_var_screeninfo const *var) {
69
	return 0;
70
}
71

72
static int stm32cube_lcd_get_var(struct fb_info *info,
73
		struct fb_var_screeninfo *var) {
74
	memset(var, 0, sizeof(*var));
75

76
#if defined STM32H745xx
77
	BSP_LCD_GetXSize(0, &var->xres);
78
	BSP_LCD_GetYSize(0, &var->yres);
79
#else
80
	var->xres = BSP_LCD_GetXSize();
81
	var->yres = BSP_LCD_GetYSize();
82
#endif
83
	var->xres_virtual = var->xres;
84
	var->yres_virtual = var->yres;
85
	var->bits_per_pixel = STM32_LCD_BPP;
86

87
	switch (STM32_LCD_BPP) {
88
	case 16:
89
		var->fmt = BGR565;
90
		break;
91
	case 32:
92
		var->fmt = BGRA8888;
93
		break;
94
	default:
95
		log_error("unknown BPP = %d\n", STM32_LCD_BPP);
96
		return -1;
97
	}
98

99
	return 0;
100
}
101

102
static void stm32cube_lcd_fillrect(struct fb_info *info,
103
		const struct fb_fillrect *rect) {
104
#if defined STM32H745xx
105
	BSP_LCD_FillRect(0, rect->dx, rect->dy, rect->width, rect->height,
106
			rect->color | 0xff000000);
107
#else
108
	BSP_LCD_SetTextColor(rect->color | 0xff000000);
109
	BSP_LCD_FillRect(rect->dx, rect->dy, rect->width, rect->height);
110
#endif
111
}
112

113
static uint32_t stm32cube_get_image_color(const struct fb_image *image, int num) {
114
	switch (image->depth) {
115
	case 1:
116
		if (image->data[num / 8] & (1 << (8 - num % 8))) {
117
			return image->fg_color;
118
		} else {
119
			return image->bg_color;
120
		}
121
	case 16:
122
		return ((uint16_t *) image->data)[num];
123
	case 32:
124
		return ((uint32_t *) image->data)[num];
125
	default:
126
		log_error("Unsupported color depth: %d\n", image->depth);
127
		return image->bg_color;
128
	}
129
}
130

131
static void stm32cube_lcd_imageblit(struct fb_info *info,
132
		const struct fb_image *image) {
133
	int dy = image->dy, dx = image->dx;
134
	int height = image->height, width = image->width;
135
	int n = 0;
136

137
	for (int j = dy; j < dy + height; j++) {
138
		for (int i = dx; i < dx + width; i++) {
139
#if defined STM32H745xx
140
			BSP_LCD_WritePixel(0, i, j, stm32cube_get_image_color(image, n));
141
#else
142
			BSP_LCD_DrawPixel(i, j, stm32cube_get_image_color(image, n));
143
#endif
144
		}
145
	}
146
}
147

148
static void ltdc_layer_init(uint16_t LayerIndex, uint32_t FB_Address, int bpp) {
149
#if defined STM32H745xx
150
#else
151
	LCD_LayerCfgTypeDef  Layercfg;
152

153
	switch (bpp) {
154
	case 16:
155
		Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
156
		break;
157
	case 32:
158
		Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
159
		break;
160
	default:
161
		return;
162
	}
163

164
	/* Layer Init */
165
	Layercfg.WindowX0 = 0;
166
	Layercfg.WindowX1 = BSP_LCD_GetXSize();
167
	Layercfg.WindowY0 = 0;
168
	Layercfg.WindowY1 = BSP_LCD_GetYSize();
169
	Layercfg.FBStartAdress = FB_Address;
170
	Layercfg.Alpha = 255;
171
	Layercfg.Alpha0 = 0;
172
	Layercfg.Backcolor.Blue = 0;
173
	Layercfg.Backcolor.Green = 0;
174
	Layercfg.Backcolor.Red = 0;
175
	Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
176
	Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
177
	Layercfg.ImageWidth = BSP_LCD_GetXSize();
178
	Layercfg.ImageHeight = BSP_LCD_GetYSize();
179

180
	HAL_LTDC_ConfigLayer(&hltdc_handler, &Layercfg, LayerIndex);
181
#endif
182
}
183

184
static irq_return_t ltdc_irq_handler(unsigned int irq_num, void *dev_id) {
185
	HAL_LTDC_IRQHandler(&hltdc_handler);
186

187
	return IRQ_HANDLED;
188
}
189

190
STATIC_IRQ_ATTACH(LTDC_IRQ, ltdc_irq_handler, NULL);
191

192
static struct fb_ops stm32cube_lcd_ops = {
193
	.fb_set_var   = stm32cube_lcd_set_var,
194
	.fb_get_var   = stm32cube_lcd_get_var,
195
	.fb_fillrect  = stm32cube_lcd_fillrect,
196
	.fb_imageblit = stm32cube_lcd_imageblit,
197
};
198

199
static int stm32cube_lcd_init(void) {
200
	char *mmap_base;
201

202
#if defined STM32H745xx
203
#if STM32_LCD_BPP == 16
204
	/* Initialize the LCD */
205
	BSP_LCD_InitEx(0, LCD_ORIENTATION_LANDSCAPE, LTDC_PIXEL_FORMAT_RGB565, STM32_LCD_WIDTH, STM32_LCD_HEIGHT);
206
#else
207
	BSP_LCD_InitEx(0, LCD_ORIENTATION_LANDSCAPE, LTDC_PIXEL_FORMAT_ARGB8888, STM32_LCD_WIDTH, STM32_LCD_HEIGHT);
208
#endif
209

210
#else
211
	if (BSP_LCD_Init() != LCD_OK) {
212
		log_error("Failed to init LCD!");
213
		return -1;
214
	}
215

216
#endif
217

218
#if USE_FB_SECTION
219
	mmap_base = (char *) &STM32_FB_SECTION_START;
220
#else
221
	mmap_base = (char *) STM32_FB_START;
222
#endif
223

224
#if STM32_LCD_BPP == 16
225
	ltdc_layer_init(LTDC_ACTIVE_LAYER, (unsigned int) mmap_base, 16);
226
#elif STM32_LCD_BPP == 32
227
	ltdc_layer_init(LTDC_ACTIVE_LAYER, (unsigned int) mmap_base, 32);
228
#else
229
	#error Unsupported STM32_LCD_BPP value
230
#endif
231

232
#if defined STM32H745xx
233
	BSP_LCD_SetBrightness(0, 100);
234
	BSP_LCD_DisplayOn(0);
235

236
	BSP_LCD_SetLayerVisible(0, 1, DISABLE);
237
	BSP_LCD_SetLayerVisible(0, LTDC_ACTIVE_LAYER, ENABLE);
238

239
	memset(mmap_base, 0, STM32_LCD_WIDTH * STM32_LCD_HEIGHT * 4);
240
#else
241
	BSP_LCD_SetXSize(STM32_LCD_WIDTH);
242
	BSP_LCD_SetYSize(STM32_LCD_HEIGHT);
243

244
	BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
245
	BSP_LCD_SetTextColor(LCD_COLOR_BLACK);
246

247
	BSP_LCD_SelectLayer(LTDC_ACTIVE_LAYER);
248

249
#ifdef STM32F769xx
250
	/* STM32746 doesn't support brightness change */
251
	BSP_LCD_SetBrightness(100);
252
#endif
253

254
	BSP_LCD_Clear(LCD_COLOR_BLACK);
255
#endif
256

257
	if (0 > irq_attach(LTDC_IRQ, ltdc_irq_handler, 0, NULL, "LTDC")) {
258
		log_error("irq_attach failed");
259
		return -1;
260
	}
261

262
	fb_create(&stm32cube_lcd_ops,
263
			mmap_base,
264
			STM32_LCD_WIDTH *
265
			STM32_LCD_HEIGHT /
266
			8 * STM32_LCD_BPP);
267

268
	return 0;
269
}
270

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.