embox
182 строки · 4.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#include "stm32f429i_discovery_lcd.h"22
23/* Initialize layer 0 as active for all F7 boards. */
24#undef LTDC_ACTIVE_LAYER25#define LTDC_ACTIVE_LAYER 026
27#include <embox/unit.h>28
29EMBOX_UNIT_INIT(stm32cube_lcd_init);30
31#define LTDC_IRQ OPTION_GET(NUMBER,ltdc_irq)32static_assert(LTDC_IRQ == LTDC_IRQn, "");33
34#define USE_FB_SECTION OPTION_GET(BOOLEAN,use_fb_section)35
36#if USE_FB_SECTION37#define STM32_FB_SECTION_START OPTION_GET(STRING,fb_section_start)38extern char STM32_FB_SECTION_START;39#else40#define STM32_FB_START OPTION_GET(NUMBER, fb_base)41#endif42
43#define STM32_LCD_HEIGHT OPTION_GET(NUMBER, height)44#define STM32_LCD_WIDTH OPTION_GET(NUMBER, width)45#define STM32_LCD_BPP OPTION_GET(NUMBER, bpp)46
47extern LTDC_HandleTypeDef LtdcHandler;48#define hltdc_handler LtdcHandler49
50static int stm32cube_lcd_set_var(struct fb_info *info,51struct fb_var_screeninfo const *var) {52return 0;53}
54
55static int stm32cube_lcd_get_var(struct fb_info *info,56struct fb_var_screeninfo *var) {57memset(var, 0, sizeof(*var));58
59var->xres = BSP_LCD_GetXSize();60var->yres = BSP_LCD_GetYSize();61
62var->xres_virtual = var->xres;63var->yres_virtual = var->yres;64
65var->bits_per_pixel = STM32_LCD_BPP;66
67var->fmt = BGR565;68
69return 0;70}
71
72static void stm32cube_lcd_fillrect(struct fb_info *info,73const struct fb_fillrect *rect)74{
75BSP_LCD_SetTextColor(rect->color | 0xff000000);76BSP_LCD_FillRect(rect->dx, rect->dy, rect->width, rect->height);77}
78
79static uint32_t stm32cube_get_image_color(const struct fb_image *image, int num)80{
81if (image->data[num / 8] & (1 << (8 - num % 8))) {82return image->fg_color;83} else {84return image->bg_color;85}86return ((uint16_t *) image->data)[num];87}
88
89static void stm32cube_lcd_imageblit(struct fb_info *info,90const struct fb_image *image)91{
92int dy = image->dy, dx = image->dx;93int height = image->height, width = image->width;94int n = 0;95
96for (int j = dy; j < dy + height; j++) {97for (int i = dx; i < dx + width; i++)98{99BSP_LCD_DrawPixel(i, j, stm32cube_get_image_color(image, n));100}101}102}
103
104static void ltdc_layer_init(uint16_t LayerIndex, uint32_t FB_Address)105{
106LCD_LayerCfgTypeDef Layercfg;107
108Layercfg.WindowX0 = 0;109Layercfg.WindowX1 = BSP_LCD_GetXSize();110Layercfg.WindowY0 = 0;111Layercfg.WindowY1 = BSP_LCD_GetYSize();112
113Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;114
115Layercfg.FBStartAdress = FB_Address;116
117Layercfg.Alpha = 255;118Layercfg.Alpha0 = 0;119
120Layercfg.Backcolor.Blue = 0;121Layercfg.Backcolor.Green = 0;122Layercfg.Backcolor.Red = 0;123
124Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;125Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;126
127Layercfg.ImageWidth = BSP_LCD_GetXSize();128Layercfg.ImageHeight = BSP_LCD_GetYSize();129
130HAL_LTDC_ConfigLayer(&hltdc_handler, &Layercfg, LayerIndex);131}
132
133static irq_return_t ltdc_irq_handler(unsigned int irq_num, void *dev_id) {134HAL_LTDC_IRQHandler(&hltdc_handler);135
136return IRQ_HANDLED;137}
138
139STATIC_IRQ_ATTACH(LTDC_IRQ, ltdc_irq_handler, NULL);140
141static struct fb_ops stm32cube_lcd_ops = {142.fb_set_var = stm32cube_lcd_set_var,143.fb_get_var = stm32cube_lcd_get_var,144.fb_fillrect = stm32cube_lcd_fillrect,145.fb_imageblit = stm32cube_lcd_imageblit,146};147
148static int stm32cube_lcd_init(void)149{
150char *mmap_base;151
152if (BSP_LCD_Init() != LCD_OK) {153log_error("Failed to init LCD!");154return -1;155}156
157#if USE_FB_SECTION158mmap_base = (char *) &STM32_FB_SECTION_START;159#else160mmap_base = (char *) STM32_FB_START;161#endif162
163ltdc_layer_init(LTDC_ACTIVE_LAYER, (uint32_t) mmap_base);164
165/* Enable The LCD */166BSP_LCD_DisplayOn();167
168BSP_LCD_Clear(0x00000000);169
170if (0 > irq_attach(LTDC_IRQ, ltdc_irq_handler, 0, NULL, "LTDC")) {171log_error("irq_attach failed");172return -1;173}174
175fb_create(&stm32cube_lcd_ops,176mmap_base,177STM32_LCD_WIDTH *178STM32_LCD_HEIGHT /1798 * STM32_LCD_BPP);180
181return 0;182}
183