embox

Форк
0
/
stm32cube_custom_lcd_drv.c 
209 строк · 4.8 Кб
1
/**
2
 * @file
3
 *
4
 * @date Oct 18, 2021
5
 * @author Anton Bondarev
6
 */
7

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

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

20
#include <embox/unit.h>
21

22
#include <stm32f746xx.h>
23
#include "stm32cube_custom_lcd.h"
24

25
EMBOX_UNIT_INIT(stm32cube_lcd_init);
26

27
#define LTDC_IRQ      OPTION_GET(NUMBER,ltdc_irq)
28
static_assert(LTDC_IRQ == LTDC_IRQn, "");
29

30
#define USE_FB_SECTION OPTION_GET(BOOLEAN,use_fb_section)
31

32
#if USE_FB_SECTION
33
#define STM32_FB_SECTION_START OPTION_GET(STRING,fb_section_start)
34
extern char STM32_FB_SECTION_START;
35
#else
36
#define STM32_FB_START  OPTION_GET(NUMBER, fb_base)
37
#endif
38

39
#define STM32_LCD_HEIGHT  OPTION_GET(NUMBER, height)
40
#define STM32_LCD_WIDTH   OPTION_GET(NUMBER, width)
41
#define STM32_LCD_BPP     OPTION_GET(NUMBER, bpp)
42

43
static_assert(STM32_LCD_BPP == 16 || STM32_LCD_BPP == 32, "");
44

45
/* Initialize layer 0 as active for all F7 boards. */
46
#undef LTDC_ACTIVE_LAYER
47
#define LTDC_ACTIVE_LAYER 0
48

49

50
extern LTDC_HandleTypeDef hLtdcHandler;
51
#define hltdc_handler hLtdcHandler
52

53
static int stm32cube_lcd_set_var(struct fb_info *info,
54
		struct fb_var_screeninfo const *var) {
55
	return 0;
56
}
57

58
static int stm32cube_lcd_get_var(struct fb_info *info,
59
		struct fb_var_screeninfo *var) {
60
	memset(var, 0, sizeof(*var));
61

62
	var->xres = bsp_lcd_getxsize();
63
	var->yres = bsp_lcd_getysize();
64
	var->xres_virtual = var->xres;
65
	var->yres_virtual = var->yres;
66
	var->bits_per_pixel = STM32_LCD_BPP;
67

68
	switch (STM32_LCD_BPP) {
69
	case 16:
70
		var->fmt = BGR565;
71
		break;
72
	case 32:
73
		var->fmt = BGRA8888;
74
		break;
75
	default:
76
		log_error("unknown BPP = %d\n", STM32_LCD_BPP);
77
		return -1;
78
	}
79

80
	return 0;
81
}
82

83
static void stm32cube_lcd_fillrect(struct fb_info *info,
84
		const struct fb_fillrect *rect) {
85

86
	bsp_lcd_settextcolor(rect->color | 0xff000000);
87
	bsp_lcd_fillrect(rect->dx, rect->dy, rect->width, rect->height);
88
}
89

90
static uint32_t stm32cube_get_image_color(const struct fb_image *image, int num) {
91
	switch (image->depth) {
92
	case 1:
93
		if (image->data[num / 8] & (1 << (8 - num % 8))) {
94
			return image->fg_color;
95
		} else {
96
			return image->bg_color;
97
		}
98
	case 16:
99
		return ((uint16_t *) image->data)[num];
100
	case 32:
101
		return ((uint32_t *) image->data)[num];
102
	default:
103
		log_error("Unsupported color depth: %d\n", image->depth);
104
		return image->bg_color;
105
	}
106
}
107

108
static void stm32cube_lcd_imageblit(struct fb_info *info,
109
		const struct fb_image *image) {
110
	int dy = image->dy, dx = image->dx;
111
	int height = image->height, width = image->width;
112
	int n = 0;
113

114
	for (int j = dy; j < dy + height; j++) {
115
		for (int i = dx; i < dx + width; i++) {
116
			bsp_lcd_drawpixel(i, j, stm32cube_get_image_color(image, n));
117
		}
118
	}
119
}
120

121
static void ltdc_layer_init(uint16_t LayerIndex, uint32_t FB_Address, int bpp) {
122
	LCD_LayerCfgTypeDef  Layercfg;
123

124
	assert(bpp == 16 || bpp == 32);
125

126
	switch (bpp) {
127
	case 16:
128
		Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
129
		break;
130
	case 32:
131
		Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
132
		break;
133
	default:
134
		return;
135
	}
136

137
	/* Layer Init */
138
	Layercfg.WindowX0 = 0;
139
	Layercfg.WindowX1 = bsp_lcd_getxsize();
140
	Layercfg.WindowY0 = 0;
141
	Layercfg.WindowY1 = bsp_lcd_getysize();
142
	Layercfg.FBStartAdress = FB_Address;
143
	Layercfg.Alpha = 255;
144
	Layercfg.Alpha0 = 0;
145
	Layercfg.Backcolor.Blue = 0;
146
	Layercfg.Backcolor.Green = 0;
147
	Layercfg.Backcolor.Red = 0;
148
	Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
149
	Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
150
	Layercfg.ImageWidth = bsp_lcd_getxsize();
151
	Layercfg.ImageHeight = bsp_lcd_getysize();
152

153
	HAL_LTDC_ConfigLayer(&hltdc_handler, &Layercfg, LayerIndex);
154
}
155

156
static irq_return_t ltdc_irq_handler(unsigned int irq_num, void *dev_id) {
157
	HAL_LTDC_IRQHandler(&hltdc_handler);
158

159
	return IRQ_HANDLED;
160
}
161

162
STATIC_IRQ_ATTACH(LTDC_IRQ, ltdc_irq_handler, NULL);
163

164
static struct fb_ops stm32cube_lcd_ops = {
165
	.fb_set_var   = stm32cube_lcd_set_var,
166
	.fb_get_var   = stm32cube_lcd_get_var,
167
	.fb_fillrect  = stm32cube_lcd_fillrect,
168
	.fb_imageblit = stm32cube_lcd_imageblit,
169
};
170

171
static int stm32cube_lcd_init(void) {
172
	char *mmap_base;
173

174
	if (bsp_lcd_init(STM32_LCD_HEIGHT, STM32_LCD_WIDTH) != LCD_OK) {
175
		log_error("Failed to init LCD!");
176
		return -1;
177
	}
178

179
#if USE_FB_SECTION
180
	mmap_base = (char *) &STM32_FB_SECTION_START;
181
#else
182
	mmap_base = (char *) STM32_FB_START;
183
#endif
184

185
	ltdc_layer_init(LTDC_ACTIVE_LAYER, (unsigned int) mmap_base, STM32_LCD_BPP);
186

187
	bsp_lcd_setxsize(STM32_LCD_WIDTH);
188
	bsp_lcd_setysize(STM32_LCD_HEIGHT);
189

190
	bsp_lcd_setbackcolor(LCD_COLOR_WHITE);
191
	bsp_lcd_settextcolor(LCD_COLOR_BLACK);
192

193
	bsp_lcd_selectlayer(LTDC_ACTIVE_LAYER);
194

195
	bsp_lcd_clear(LCD_COLOR_BLACK);
196

197
	if (0 > irq_attach(LTDC_IRQ, ltdc_irq_handler, 0, NULL, "LTDC")) {
198
		log_error("irq_attach failed");
199
		return -1;
200
	}
201

202
	fb_create(&stm32cube_lcd_ops,
203
			mmap_base,
204
			STM32_LCD_WIDTH *
205
			STM32_LCD_HEIGHT /
206
			8 * STM32_LCD_BPP);
207

208
	return 0;
209
}
210

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

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

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

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