Various fixes around Companion trainer mode (#7116)
[opentx.git] / radio / src / targets / horus / lcd_driver.cpp
blob110db000762bac83de37771ec20592c7588dbff0
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include "opentx.h"
23 #define HBP 42
24 #define VBP 12
26 #define HSW 2
27 #define VSW 10
29 #define HFP 3
30 #define VFP 2
32 #define LCD_FIRST_LAYER 0
33 #define LCD_SECOND_LAYER 1
35 uint8_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(display_t)] __SDRAM;
36 uint8_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(display_t)] __SDRAM;
37 uint8_t LCD_BACKUP_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(display_t)] __SDRAM;
39 uint32_t CurrentLayer = LCD_FIRST_LAYER;
41 #define NRST_LOW() do { LCD_GPIO_NRST->BSRRH = LCD_GPIO_PIN_NRST; } while(0)
42 #define NRST_HIGH() do { LCD_GPIO_NRST->BSRRL = LCD_GPIO_PIN_NRST; } while(0)
44 static void LCD_AF_GPIOConfig(void)
46 GPIO_InitTypeDef GPIO_InitStructure;
48 /* GPIOs Configuration */
50 +------------------------+-----------------------+----------------------------+
51 + LCD pins assignment +
52 +------------------------+-----------------------+----------------------------
53 | | LCD_TFT G2 <-> PJ.09 | |
54 | LCD_TFT R3 <-> PJ.02 | LCD_TFT G3 <-> PJ.10 | LCD_TFT B3 <-> PJ.15 |
55 | LCD_TFT R4 <-> PJ.03 | LCD_TFT G4 <-> PJ.11 | LCD_TFT B4 <-> PK.03 |
56 | LCD_TFT R5 <-> PJ.04 | LCD_TFT G5 <-> PK.00 | LCD_TFT B5 <-> PK.04 |
57 | LCD_TFT R6 <-> PJ.05 | LCD_TFT G6 <-> PK.01 | LCD_TFT B6 <-> PK.05 |
58 | LCD_TFT R7 <-> PJ.06 | LCD_TFT G7 <-> PK.02 | LCD_TFT B7 <-> PK.06 |
59 -------------------------------------------------------------------------------
60 | LCD_TFT HSYNC <-> PI.12 | LCDTFT VSYNC <-> PI.13 |
61 | LCD_TFT CLK <-> PI.14 | LCD_TFT DE <-> PK.07 ///
62 -----------------------------------------------------
63 | LCD_CS <-> PI.10 |LCD_SCK<->PI.11
64 -----------------------------------------------------
66 // GPIOI configuration
67 GPIO_PinAFConfig(GPIOI, GPIO_PinSource12, GPIO_AF_LTDC);
68 GPIO_PinAFConfig(GPIOI, GPIO_PinSource13, GPIO_AF_LTDC);
69 GPIO_PinAFConfig(GPIOI, GPIO_PinSource14, GPIO_AF_LTDC);
71 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
72 GPIO_InitStructure.GPIO_Speed =GPIO_Speed_2MHz;
73 GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF;
74 GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
75 GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
76 GPIO_Init(GPIOI, &GPIO_InitStructure);
78 GPIO_PinAFConfig(GPIOK, GPIO_PinSource7, GPIO_AF_LTDC);
80 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
81 GPIO_Init(GPIOK, &GPIO_InitStructure);
83 // GPIOJ configuration
84 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource2, GPIO_AF_LTDC);
85 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource3, GPIO_AF_LTDC);
86 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource4, GPIO_AF_LTDC);
87 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource5, GPIO_AF_LTDC);
88 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource6, GPIO_AF_LTDC);
89 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource9, GPIO_AF_LTDC);
90 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource10, GPIO_AF_LTDC);
91 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource11, GPIO_AF_LTDC);
92 GPIO_PinAFConfig(GPIOJ, GPIO_PinSource15, GPIO_AF_LTDC);
94 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | \
95 GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_15;
97 GPIO_Init(GPIOJ, &GPIO_InitStructure);
99 // GPIOK configuration
100 GPIO_PinAFConfig(GPIOK, GPIO_PinSource0, GPIO_AF_LTDC);
101 GPIO_PinAFConfig(GPIOK, GPIO_PinSource1, GPIO_AF_LTDC);
102 GPIO_PinAFConfig(GPIOK, GPIO_PinSource2, GPIO_AF_LTDC);
103 GPIO_PinAFConfig(GPIOK, GPIO_PinSource3, GPIO_AF_LTDC);
104 GPIO_PinAFConfig(GPIOK, GPIO_PinSource4, GPIO_AF_LTDC);
105 GPIO_PinAFConfig(GPIOK, GPIO_PinSource5, GPIO_AF_LTDC);
106 GPIO_PinAFConfig(GPIOK, GPIO_PinSource6, GPIO_AF_LTDC);
108 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 ;
110 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
111 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
112 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
113 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
114 GPIO_Init(GPIOK, &GPIO_InitStructure);
117 static void LCD_NRSTConfig(void)
119 GPIO_InitTypeDef GPIO_InitStructure;
120 GPIO_InitStructure.GPIO_Pin = LCD_GPIO_PIN_NRST;
121 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
122 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
123 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
124 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
125 GPIO_Init(LCD_GPIO_NRST, &GPIO_InitStructure);
128 // TODO delay function
129 static void delay3(uint32_t nCount)
131 uint32_t index = 0;
132 for(index = (1000 * 100 * nCount); index != 0; --index)
134 __asm("nop\n");
138 static void lcd_reset(void)
140 NRST_HIGH();
141 delay3(1);
143 NRST_LOW(); // RESET();
144 delay3(20);
146 NRST_HIGH();
147 delay3(30);
150 void LCD_Init_LTDC(void)
152 LTDC_InitTypeDef LTDC_InitStruct;
154 /* Configure PLLSAI prescalers for LCD */
155 /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
156 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAI_N = 192 Mhz */
157 /* PLLLCDCLK = PLLSAI_VCO Output/PLL_LTDC = 192/3 = 64 Mhz */
158 /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 64/4 = 16 Mhz */
159 //second pam is for audio
160 //third pam is for LCD
161 RCC_PLLSAIConfig(192, 6, 3);
162 RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div4); //Modify by Fy
163 /* Enable PLLSAI Clock */
164 RCC_PLLSAICmd(ENABLE);
166 /* Wait for PLLSAI activation */
167 while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY) == RESET)
171 /* LTDC Configuration *********************************************************/
172 /* Polarity configuration */
173 /* Initialize the horizontal synchronization polarity as active low */
174 LTDC_InitStruct.LTDC_HSPolarity = LTDC_HSPolarity_AL;
175 /* Initialize the vertical synchronization polarity as active low */
176 LTDC_InitStruct.LTDC_VSPolarity = LTDC_VSPolarity_AL;
177 /* Initialize the data enable polarity as active low */
178 LTDC_InitStruct.LTDC_DEPolarity = LTDC_DEPolarity_AL;
179 /* Initialize the pixel clock polarity as input pixel clock */
180 LTDC_InitStruct.LTDC_PCPolarity = LTDC_PCPolarity_IPC;
182 /* Configure R,G,B component values for LCD background color */
183 LTDC_InitStruct.LTDC_BackgroundRedValue = 0;
184 LTDC_InitStruct.LTDC_BackgroundGreenValue = 0;
185 LTDC_InitStruct.LTDC_BackgroundBlueValue = 0;
187 /* Configure horizontal synchronization width */
188 LTDC_InitStruct.LTDC_HorizontalSync = HSW;
189 /* Configure vertical synchronization height */
190 LTDC_InitStruct.LTDC_VerticalSync = VSW;
191 /* Configure accumulated horizontal back porch */
192 LTDC_InitStruct.LTDC_AccumulatedHBP = HBP;
193 /* Configure accumulated vertical back porch */
194 LTDC_InitStruct.LTDC_AccumulatedVBP = VBP;
195 /* Configure accumulated active width */
196 LTDC_InitStruct.LTDC_AccumulatedActiveW = LCD_W + HBP;
197 /* Configure accumulated active height */
198 LTDC_InitStruct.LTDC_AccumulatedActiveH = LCD_H + VBP;
199 /* Configure total width */
200 LTDC_InitStruct.LTDC_TotalWidth = LCD_W + HBP + HFP;
201 /* Configure total height */
202 LTDC_InitStruct.LTDC_TotalHeigh = LCD_H + VBP + VFP;
204 // init ltdc
205 LTDC_Init(&LTDC_InitStruct);
207 #if 0
208 LTDC_ITConfig(LTDC_IER_LIE, ENABLE);
209 NVIC_InitTypeDef NVIC_InitStructure;
210 NVIC_InitStructure.NVIC_IRQChannel = LTDC_IRQn;
211 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = LTDC_IRQ_PRIO;
212 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pr e-emption priority. */;
213 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
214 NVIC_Init( &NVIC_InitStructure );
216 DMA2D_ITConfig(DMA2D_CR_TCIE, ENABLE);
217 NVIC_InitStructure.NVIC_IRQChannel = DMA2D_IRQn;
218 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SCREEN_IRQ_PRIO;
219 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pr e-emption priority. */;
220 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
221 NVIC_Init( &NVIC_InitStructure );
223 DMA2D->IFCR = (unsigned long)DMA2D_IFSR_CTCIF;
224 #endif
228 * @brief Initializes the LCD Layers.
229 * @param None
230 * @retval None
232 void LCD_LayerInit()
234 LTDC_Layer_InitTypeDef LTDC_Layer_InitStruct;
236 /* Windowing configuration */
237 /* In this case all the active display area is used to display a picture then :
238 Horizontal start = horizontal synchronization + Horizontal back porch = 30
239 Horizontal stop = Horizontal start + window width -1 = 30 + 240 -1
240 Vertical start = vertical synchronization + vertical back porch = 4
241 Vertical stop = Vertical start + window height -1 = 4 + 320 -1 */
242 LTDC_Layer_InitStruct.LTDC_HorizontalStart = HBP + 1;
243 LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_W + HBP);
244 LTDC_Layer_InitStruct.LTDC_VerticalStart = VBP + 1;;
245 LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_H + VBP);
247 /* Pixel Format configuration*/
248 LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_RGB565;
249 /* Alpha constant (255 totally opaque) */
250 LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 255;
251 /* Default Color configuration (configure A,R,G,B component values) */
252 LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0;
253 LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0;
254 LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0;
255 LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0;
257 /* Configure blending factors */
258 LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_CA;
259 LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_CA;
261 /* the length of one line of pixels in bytes + 3 then :
262 Line Lenth = Active high width x number of bytes per pixel + 3
263 Active high width = LCD_W
264 number of bytes per pixel = 2 (pixel_format : RGB565)
266 LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_W * 2) + 3);
267 /* the pitch is the increment from the start of one line of pixels to the
268 start of the next line in bytes, then :
269 Pitch = Active high width x number of bytes per pixel */
270 LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_W * 2);
272 /* Configure the number of lines */
273 LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_H;
275 /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */
276 LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t)LCD_FIRST_FRAME_BUFFER;
278 /* Initialize LTDC layer 1 */
279 LTDC_LayerInit(LTDC_Layer1, &LTDC_Layer_InitStruct);
281 /* Configure Layer 2 */
282 LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA;
283 LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA;
285 /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */
286 LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t)LCD_SECOND_FRAME_BUFFER;
288 /* Initialize LTDC layer 2 */
289 LTDC_LayerInit(LTDC_Layer2, &LTDC_Layer_InitStruct);
291 /* LTDC configuration reload */
292 LTDC_ReloadConfig(LTDC_IMReload);
294 LTDC_LayerCmd(LTDC_Layer1, ENABLE);
295 LTDC_LayerCmd(LTDC_Layer2, ENABLE);
297 LTDC_ReloadConfig(LTDC_IMReload);
299 /* dithering activation */
300 LTDC_DitherCmd(ENABLE);
303 /*********************************output****************************************/
305 * @brief Initializes the LCD.
306 * @param None
307 * @retval None
309 void LCD_Init(void)
311 /* Reset the LCD --------------------------------------------------------*/
312 LCD_NRSTConfig();
313 lcd_reset();
315 /* Configure the LCD Control pins */
316 LCD_AF_GPIOConfig();
318 LCD_Init_LTDC();
321 BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_FIRST_FRAME_BUFFER);
322 BitmapBuffer lcdBuffer2(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_SECOND_FRAME_BUFFER);
323 BitmapBuffer * lcd = &lcdBuffer1;
326 * @brief Sets the LCD Layer.
327 * @param Layerx: specifies the Layer foreground or background.
328 * @retval None
330 void LCD_SetLayer(uint32_t Layerx)
332 if (Layerx == LCD_FIRST_LAYER) {
333 lcd = &lcdBuffer1;
334 CurrentLayer = LCD_FIRST_LAYER;
336 else {
337 lcd = &lcdBuffer2;
338 CurrentLayer = LCD_SECOND_LAYER;
343 * @brief Configure the transparency.
344 * @param transparency: specifies the transparency,
345 * This parameter must range from 0x00 to 0xFF.
346 * @retval None
348 void LCD_SetTransparency(uint8_t transparency)
350 if (CurrentLayer == LCD_FIRST_LAYER) {
351 LTDC_LayerAlpha(LTDC_Layer1, transparency);
353 else {
354 LTDC_LayerAlpha(LTDC_Layer2, transparency);
356 LTDC_ReloadConfig(LTDC_IMReload);
359 void lcdInit(void)
361 /* Initialize the LCD */
362 LCD_Init();
363 LCD_LayerInit();
365 /* Enable LCD display */
366 LTDC_Cmd(ENABLE);
368 /* Set Background layer */
369 LCD_SetLayer(LCD_FIRST_LAYER);
370 // lcdClear();
371 LCD_SetTransparency(0);
373 /* Set Foreground layer */
374 LCD_SetLayer(LCD_SECOND_LAYER);
375 lcd->clear();
376 LCD_SetTransparency(255);
379 void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color)
381 #if defined(PCBX10)
382 x = destw - (x + w);
383 y = desth - (y + h);
384 #endif
386 DMA2D_DeInit();
388 DMA2D_InitTypeDef DMA2D_InitStruct;
389 DMA2D_InitStruct.DMA2D_Mode = DMA2D_R2M;
390 DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565;
391 DMA2D_InitStruct.DMA2D_OutputGreen = (0x07E0 & color) >> 5;
392 DMA2D_InitStruct.DMA2D_OutputBlue = 0x001F & color;
393 DMA2D_InitStruct.DMA2D_OutputRed = (0xF800 & color) >> 11;
394 DMA2D_InitStruct.DMA2D_OutputAlpha = 0x0F;
395 DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest) + 2*(destw*y + x);
396 DMA2D_InitStruct.DMA2D_OutputOffset = (destw - w);
397 DMA2D_InitStruct.DMA2D_NumberOfLine = h;
398 DMA2D_InitStruct.DMA2D_PixelPerLine = w;
399 DMA2D_Init(&DMA2D_InitStruct);
401 /* Start Transfer */
402 DMA2D_StartTransfer();
404 /* Wait for CTC Flag activation */
405 while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET);
408 void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h)
410 #if defined(PCBX10)
411 x = destw - (x + w);
412 y = desth - (y + h);
413 srcx = srcw - (srcx + w);
414 srcy = srch - (srcy + h);
415 #endif
417 DMA2D_DeInit();
419 DMA2D_InitTypeDef DMA2D_InitStruct;
420 DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M;
421 DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565;
422 DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest + y*destw + x);
423 DMA2D_InitStruct.DMA2D_OutputGreen = 0;
424 DMA2D_InitStruct.DMA2D_OutputBlue = 0;
425 DMA2D_InitStruct.DMA2D_OutputRed = 0;
426 DMA2D_InitStruct.DMA2D_OutputAlpha = 0;
427 DMA2D_InitStruct.DMA2D_OutputOffset = destw - w;
428 DMA2D_InitStruct.DMA2D_NumberOfLine = h;
429 DMA2D_InitStruct.DMA2D_PixelPerLine = w;
430 DMA2D_Init(&DMA2D_InitStruct);
432 DMA2D_FG_InitTypeDef DMA2D_FG_InitStruct;
433 DMA2D_FG_StructInit(&DMA2D_FG_InitStruct);
434 DMA2D_FG_InitStruct.DMA2D_FGMA = CONVERT_PTR_UINT(src + srcy*srcw + srcx);
435 DMA2D_FG_InitStruct.DMA2D_FGO = srcw - w;
436 DMA2D_FG_InitStruct.DMA2D_FGCM = CM_RGB565;
437 DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE;
438 DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_VALUE = 0;
439 DMA2D_FGConfig(&DMA2D_FG_InitStruct);
441 /* Start Transfer */
442 DMA2D_StartTransfer();
444 /* Wait for CTC Flag activation */
445 while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET);
448 void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h)
450 #if defined(PCBX10)
451 x = destw - (x + w);
452 y = desth - (y + h);
453 srcx = srcw - (srcx + w);
454 srcy = srch - (srcy + h);
455 #endif
457 DMA2D_DeInit();
459 DMA2D_InitTypeDef DMA2D_InitStruct;
460 DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M_BLEND;
461 DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565;
462 DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest + y*destw + x);
463 DMA2D_InitStruct.DMA2D_OutputGreen = 0;
464 DMA2D_InitStruct.DMA2D_OutputBlue = 0;
465 DMA2D_InitStruct.DMA2D_OutputRed = 0;
466 DMA2D_InitStruct.DMA2D_OutputAlpha = 0;
467 DMA2D_InitStruct.DMA2D_OutputOffset = destw - w;
468 DMA2D_InitStruct.DMA2D_NumberOfLine = h;
469 DMA2D_InitStruct.DMA2D_PixelPerLine = w;
470 DMA2D_Init(&DMA2D_InitStruct);
472 DMA2D_FG_InitTypeDef DMA2D_FG_InitStruct;
473 DMA2D_FG_StructInit(&DMA2D_FG_InitStruct);
474 DMA2D_FG_InitStruct.DMA2D_FGMA = CONVERT_PTR_UINT(src + srcy*srcw + srcx);
475 DMA2D_FG_InitStruct.DMA2D_FGO = srcw - w;
476 DMA2D_FG_InitStruct.DMA2D_FGCM = CM_ARGB4444;
477 DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE;
478 DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_VALUE = 0;
479 DMA2D_FGConfig(&DMA2D_FG_InitStruct);
481 DMA2D_BG_InitTypeDef DMA2D_BG_InitStruct;
482 DMA2D_BG_StructInit(&DMA2D_BG_InitStruct);
483 DMA2D_BG_InitStruct.DMA2D_BGMA = CONVERT_PTR_UINT(dest + y*destw + x);
484 DMA2D_BG_InitStruct.DMA2D_BGO = destw - w;
485 DMA2D_BG_InitStruct.DMA2D_BGCM = CM_RGB565;
486 DMA2D_BG_InitStruct.DMA2D_BGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE;
487 DMA2D_BG_InitStruct.DMA2D_BGPFC_ALPHA_VALUE = 0;
488 DMA2D_BGConfig(&DMA2D_BG_InitStruct);
490 /* Start Transfer */
491 DMA2D_StartTransfer();
493 /* Wait for CTC Flag activation */
494 while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET);
497 void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format)
499 DMA2D_DeInit();
501 DMA2D_InitTypeDef DMA2D_InitStruct;
502 DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M_PFC;
503 DMA2D_InitStruct.DMA2D_CMode = format;
504 DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest);
505 DMA2D_InitStruct.DMA2D_OutputGreen = 0;
506 DMA2D_InitStruct.DMA2D_OutputBlue = 0;
507 DMA2D_InitStruct.DMA2D_OutputRed = 0;
508 DMA2D_InitStruct.DMA2D_OutputAlpha = 0;
509 DMA2D_InitStruct.DMA2D_OutputOffset = 0;
510 DMA2D_InitStruct.DMA2D_NumberOfLine = h;
511 DMA2D_InitStruct.DMA2D_PixelPerLine = w;
512 DMA2D_Init(&DMA2D_InitStruct);
514 DMA2D_FG_InitTypeDef DMA2D_FG_InitStruct;
515 DMA2D_FG_StructInit(&DMA2D_FG_InitStruct);
516 DMA2D_FG_InitStruct.DMA2D_FGMA = CONVERT_PTR_UINT(src);
517 DMA2D_FG_InitStruct.DMA2D_FGO = 0;
518 DMA2D_FG_InitStruct.DMA2D_FGCM = CM_ARGB8888;
519 DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_MODE = REPLACE_ALPHA_VALUE;
520 DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_VALUE = 0;
521 DMA2D_FGConfig(&DMA2D_FG_InitStruct);
523 /* Start Transfer */
524 DMA2D_StartTransfer();
526 /* Wait for CTC Flag activation */
527 while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET);
530 void DMAcopy(void * src, void * dest, int len)
532 DMA2D_DeInit();
534 DMA2D_InitTypeDef DMA2D_InitStruct;
535 DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M;
536 DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565;
537 DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest);
538 DMA2D_InitStruct.DMA2D_OutputGreen = 0;
539 DMA2D_InitStruct.DMA2D_OutputBlue = 0;
540 DMA2D_InitStruct.DMA2D_OutputRed = 0;
541 DMA2D_InitStruct.DMA2D_OutputAlpha = 0;
542 DMA2D_InitStruct.DMA2D_OutputOffset = 0;
543 DMA2D_InitStruct.DMA2D_NumberOfLine = LCD_H;
544 DMA2D_InitStruct.DMA2D_PixelPerLine = LCD_W;
545 DMA2D_Init(&DMA2D_InitStruct);
547 DMA2D_FG_InitTypeDef DMA2D_FG_InitStruct;
548 DMA2D_FG_StructInit(&DMA2D_FG_InitStruct);
549 DMA2D_FG_InitStruct.DMA2D_FGMA = CONVERT_PTR_UINT(src);
550 DMA2D_FG_InitStruct.DMA2D_FGO = 0;
551 DMA2D_FG_InitStruct.DMA2D_FGCM = CM_RGB565;
552 DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE;
553 DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_VALUE = 0;
554 DMA2D_FGConfig(&DMA2D_FG_InitStruct);
556 /* Start Transfer */
557 DMA2D_StartTransfer();
559 /* Wait for CTC Flag activation */
560 while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET);
563 void lcdStoreBackupBuffer()
565 DMAcopy(lcd->getData(), LCD_BACKUP_FRAME_BUFFER, DISPLAY_BUFFER_SIZE * sizeof(display_t));
568 int lcdRestoreBackupBuffer()
570 DMAcopy(LCD_BACKUP_FRAME_BUFFER, lcd->getData(), DISPLAY_BUFFER_SIZE * sizeof(display_t));
571 return 1;
574 void lcdRefresh()
576 LCD_SetTransparency(255);
577 if (CurrentLayer == LCD_FIRST_LAYER)
578 LCD_SetLayer(LCD_SECOND_LAYER);
579 else
580 LCD_SetLayer(LCD_FIRST_LAYER);
581 LCD_SetTransparency(0);