source: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/stlcd_otm8009a/stlcd_otm8009a.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 54.4 KB
Line 
1/*
2 * TOPPERS BASE PLATFORM MIDDLEWARE
3 *
4 * Copyright (C) 2017-2018 by TOPPERS PROJECT
5 * Educational Working Group.
6 *
7 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 * @(#) $Id$
37 */
38/**
39 ******************************************************************************
40 * @attention
41 *
42 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
43 *
44 * Redistribution and use in source and binary forms, with or without modification,
45 * are permitted provided that the following conditions are met:
46 * 1. Redistributions of source code must retain the above copyright notice,
47 * this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright notice,
49 * this list of conditions and the following disclaimer in the documentation
50 * and/or other materials provided with the distribution.
51 * 3. Neither the name of STMicroelectronics nor the names of its contributors
52 * may be used to endorse or promote products derived from this software
53 * without specific prior written permission.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
56 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
61 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
62 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
63 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
64 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65 *
66 ******************************************************************************
67 */
68
69#include "stlcd_otm8009a.h"
70#include "kernel_cfg.h"
71
72#define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
73#define sil_andw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
74#define sil_modw_mem(a, b, c) sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
75
76
77
78/** @defgroup STM32F769I-DISCOVERY_LCD_Private_Macros LCD Private Macros
79 * @{
80 */
81#define ABS(X) ((X) > 0 ? (X) : -(X))
82
83#define POLY_X(Z) ((int32_t)((Points + (Z))->X))
84#define POLY_Y(Z) ((int32_t)((Points + (Z))->Y))
85
86/*
87 * @brief Constant tables of register settings used to transmit DSI
88 * command packets as power up initialization sequence of the KoD LCD (OTM8009A LCD Driver)
89 */
90static const uint8_t lcdRegData1[] = {0x80,0x09,0x01,0xFF};
91static const uint8_t lcdRegData2[] = {0x80,0x09,0xFF};
92static const uint8_t lcdRegData3[] = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01,0xE1};
93static const uint8_t lcdRegData4[] = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01,0xE2};
94static const uint8_t lcdRegData5[] = {0x79,0x79,0xD8};
95static const uint8_t lcdRegData6[] = {0x00,0x01,0xB3};
96static const uint8_t lcdRegData7[] = {0x85,0x01,0x00,0x84,0x01,0x00,0xCE};
97static const uint8_t lcdRegData8[] = {0x18,0x04,0x03,0x39,0x00,0x00,0x00,0x18,0x03,0x03,0x3A,0x00,0x00,0x00,0xCE};
98static const uint8_t lcdRegData9[] = {0x18,0x02,0x03,0x3B,0x00,0x00,0x00,0x18,0x01,0x03,0x3C,0x00,0x00,0x00,0xCE};
99static const uint8_t lcdRegData10[] = {0x01,0x01,0x20,0x20,0x00,0x00,0x01,0x02,0x00,0x00,0xCF};
100static const uint8_t lcdRegData11[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
101static const uint8_t lcdRegData12[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
102static const uint8_t lcdRegData13[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
103static const uint8_t lcdRegData14[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
104static const uint8_t lcdRegData15[] = {0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
105static const uint8_t lcdRegData16[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0xCB};
106static const uint8_t lcdRegData17[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
107static const uint8_t lcdRegData18[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCB};
108static const uint8_t lcdRegData19[] = {0x00,0x26,0x09,0x0B,0x01,0x25,0x00,0x00,0x00,0x00,0xCC};
109static const uint8_t lcdRegData20[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0x0A,0x0C,0x02,0xCC};
110static const uint8_t lcdRegData21[] = {0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC};
111static const uint8_t lcdRegData22[] = {0x00,0x25,0x0C,0x0A,0x02,0x26,0x00,0x00,0x00,0x00,0xCC};
112static const uint8_t lcdRegData23[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x0B,0x09,0x01,0xCC};
113static const uint8_t lcdRegData24[] = {0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC};
114static const uint8_t lcdRegData25[] = {0xFF,0xFF,0xFF,0xFF};
115/*
116 * CASET value (Column Address Set) : X direction LCD GRAM boundaries
117 * depending on LCD orientation mode and PASET value (Page Address Set) : Y direction
118 * LCD GRAM boundaries depending on LCD orientation mode
119 * XS[15:0] = 0x000 = 0, XE[15:0] = 0x31F = 799 for landscape mode : apply to CASET
120 * YS[15:0] = 0x000 = 0, YE[15:0] = 0x31F = 799 for portrait mode : : apply to PASET
121 */
122static const uint8_t lcdRegData27[] = {0x00, 0x00, 0x03, 0x1F, OTM8009A_CMD_CASET};
123/*
124 * XS[15:0] = 0x000 = 0, XE[15:0] = 0x1DF = 479 for portrait mode : apply to CASET
125 * YS[15:0] = 0x000 = 0, YE[15:0] = 0x1DF = 479 for landscape mode : apply to PASET
126 */
127static const uint8_t lcdRegData28[] = {0x00, 0x00, 0x01, 0xDF, OTM8009A_CMD_PASET};
128
129
130static const uint8_t ShortRegData1[] = {OTM8009A_CMD_NOP, 0x00};
131static const uint8_t ShortRegData2[] = {OTM8009A_CMD_NOP, 0x80};
132static const uint8_t ShortRegData3[] = {0xC4, 0x30};
133static const uint8_t ShortRegData4[] = {OTM8009A_CMD_NOP, 0x8A};
134static const uint8_t ShortRegData5[] = {0xC4, 0x40};
135static const uint8_t ShortRegData6[] = {OTM8009A_CMD_NOP, 0xB1};
136static const uint8_t ShortRegData7[] = {0xC5, 0xA9};
137static const uint8_t ShortRegData8[] = {OTM8009A_CMD_NOP, 0x91};
138static const uint8_t ShortRegData9[] = {0xC5, 0x34};
139static const uint8_t ShortRegData10[] = {OTM8009A_CMD_NOP, 0xB4};
140static const uint8_t ShortRegData11[] = {0xC0, 0x50};
141static const uint8_t ShortRegData12[] = {0xD9, 0x4E};
142static const uint8_t ShortRegData13[] = {OTM8009A_CMD_NOP, 0x81};
143static const uint8_t ShortRegData14[] = {0xC1, 0x66};
144static const uint8_t ShortRegData15[] = {OTM8009A_CMD_NOP, 0xA1};
145static const uint8_t ShortRegData16[] = {0xC1, 0x08};
146static const uint8_t ShortRegData17[] = {OTM8009A_CMD_NOP, 0x92};
147static const uint8_t ShortRegData18[] = {0xC5, 0x01};
148static const uint8_t ShortRegData19[] = {OTM8009A_CMD_NOP, 0x95};
149static const uint8_t ShortRegData20[] = {OTM8009A_CMD_NOP, 0x94};
150static const uint8_t ShortRegData21[] = {0xC5, 0x33};
151static const uint8_t ShortRegData22[] = {OTM8009A_CMD_NOP, 0xA3};
152static const uint8_t ShortRegData23[] = {0xC0, 0x1B};
153static const uint8_t ShortRegData24[] = {OTM8009A_CMD_NOP, 0x82};
154static const uint8_t ShortRegData25[] = {0xC5, 0x83};
155static const uint8_t ShortRegData26[] = {0xC4, 0x83};
156static const uint8_t ShortRegData27[] = {0xC1, 0x0E};
157static const uint8_t ShortRegData28[] = {OTM8009A_CMD_NOP, 0xA6};
158static const uint8_t ShortRegData29[] = {OTM8009A_CMD_NOP, 0xA0};
159static const uint8_t ShortRegData30[] = {OTM8009A_CMD_NOP, 0xB0};
160static const uint8_t ShortRegData31[] = {OTM8009A_CMD_NOP, 0xC0};
161static const uint8_t ShortRegData32[] = {OTM8009A_CMD_NOP, 0xD0};
162static const uint8_t ShortRegData33[] = {OTM8009A_CMD_NOP, 0x90};
163static const uint8_t ShortRegData34[] = {OTM8009A_CMD_NOP, 0xE0};
164static const uint8_t ShortRegData35[] = {OTM8009A_CMD_NOP, 0xF0};
165static const uint8_t ShortRegData36[] = {OTM8009A_CMD_SLPOUT, 0x00};
166static const uint8_t ShortRegData37[] = {OTM8009A_CMD_COLMOD, OTM8009A_COLMOD_RGB565};
167static const uint8_t ShortRegData38[] = {OTM8009A_CMD_COLMOD, OTM8009A_COLMOD_RGB888};
168static const uint8_t ShortRegData39[] = {OTM8009A_CMD_MADCTR, OTM8009A_MADCTR_MODE_LANDSCAPE};
169static const uint8_t ShortRegData40[] = {OTM8009A_CMD_WRDISBV, 0x7F};
170static const uint8_t ShortRegData41[] = {OTM8009A_CMD_WRCTRLD, 0x2C};
171static const uint8_t ShortRegData42[] = {OTM8009A_CMD_WRCABC, 0x02};
172static const uint8_t ShortRegData43[] = {OTM8009A_CMD_WRCABCMB, 0xFF};
173static const uint8_t ShortRegData44[] = {OTM8009A_CMD_DISPON, 0x00};
174static const uint8_t ShortRegData45[] = {OTM8009A_CMD_RAMWR, 0x00};
175static const uint8_t ShortRegData46[] = {0xCF, 0x00};
176static const uint8_t ShortRegData47[] = {0xC5, 0x66};
177static const uint8_t ShortRegData48[] = {OTM8009A_CMD_NOP, 0xB6};
178static const uint8_t ShortRegData49[] = {0xF5, 0x06};
179
180
181/** @defgroup STM32F769I-DISCOVERY_LCD_Exported_Variables STM32F769I DISCOVERY LCD Exported Variables
182 * @{
183 */
184static DMA2D_Handle_t hdma2d_discovery;
185static LTDC_Handle_t hltdc_discovery;
186static DSI_Handle_t hdsi_discovery;
187/**
188 * @}
189 */
190
191/**
192 * @}
193 */
194
195/** @defgroup STM32F769I-DISCOVERY_LCD_Private_FunctionPrototypes LCD Private FunctionPrototypes
196 * @{
197 */
198static void FillTriangle(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
199static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex);
200static void LL_ConvertLineToARGB8888(void * pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode);
201/**
202 * @}
203 */
204/**
205 * @brief DCS or Generic short/long write command
206 * @param NbParams: Number of parameters. It indicates the write command mode:
207 * If inferior to 2, a long write command is performed else short.
208 * @param pParams: Pointer to parameter values table.
209 * @retval HAL status
210 */
211static void
212DSI_IO_WriteCmd(DSI_Handle_t *hdsi, uint32_t NbrParams, uint8_t *pParams)
213{
214 if(NbrParams <= 1){
215 dsi_swrite(hdsi, LCD_OTM8009A_ID, DSI_DCS_SHORT_PKT_WRITE_P1, pParams[0], pParams[1]);
216 }
217 else{
218 dsi_lwrite(hdsi, LCD_OTM8009A_ID, DSI_DCS_LONG_PKT_WRITE, NbrParams, pParams[NbrParams], pParams);
219 }
220}
221
222/**
223 * @brief Initializes the LCD KoD display part by communication in DSI mode in Video Mode
224 * with IC Display Driver OTM8009A (see IC Driver specification for more information).
225 * @param hdsi_eval : pointer on DSI configuration structure
226 * @param hdsivideo_handle : pointer on DSI video mode configuration structure
227 * @retval Status
228 */
229static uint8_t
230OTM8009A_Init(DSI_Handle_t *hdsi, uint32_t ColorCoding, uint32_t orientation)
231{
232 /* Enable CMD2 to access vendor specific commands */
233 /* Enter in command 2 mode and set EXTC to enable address shift function (0x00) */
234 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
235 DSI_IO_WriteCmd(hdsi, 3, (uint8_t *)lcdRegData1);
236
237 /* Enter ORISE Command 2 */
238 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2); /* Shift address to 0x80 */
239 DSI_IO_WriteCmd(hdsi, 2, (uint8_t *)lcdRegData2);
240
241 /////////////////////////////////////////////////////////////////////
242 /* SD_PCH_CTRL - 0xC480h - 129th parameter - Default 0x00 */
243 /* Set SD_PT */
244 /* -> Source output level during porch and non-display area to GND */
245 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2);
246 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData3);
247 dly_tsk(10);
248 /* Not documented */
249 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData4);
250 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData5);
251 dly_tsk(10);
252 /////////////////////////////////////////////////////////////////////
253
254 /* PWR_CTRL4 - 0xC4B0h - 178th parameter - Default 0xA8 */
255 /* Set gvdd_en_test */
256 /* -> enable GVDD test mode !!! */
257 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData6);
258 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData7);
259
260 /* PWR_CTRL2 - 0xC590h - 146th parameter - Default 0x79 */
261 /* Set pump 4 vgh voltage */
262 /* -> from 15.0v down to 13.0v */
263 /* Set pump 5 vgh voltage */
264 /* -> from -12.0v downto -9.0v */
265 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData8);
266 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData9);
267
268 /* P_DRV_M - 0xC0B4h - 181th parameter - Default 0x00 */
269 /* -> Column inversion */
270 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData10);
271 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData11);
272
273 /* VCOMDC - 0xD900h - 1st parameter - Default 0x39h */
274 /* VCOM Voltage settings */
275 /* -> from -1.0000v downto -1.2625v */
276 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
277 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData12);
278
279 /* Oscillator adjustment for Idle/Normal mode (LPDT only) set to 65Hz (default is 60Hz) */
280 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData13);
281 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData14);
282
283 /* Video mode internal */
284 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData15);
285 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData16);
286
287 /* PWR_CTRL2 - 0xC590h - 147h parameter - Default 0x00 */
288 /* Set pump 4&5 x6 */
289 /* -> ONLY VALID when PUMP4_EN_ASDM_HV = "0" */
290 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData17);
291 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData18);
292
293 /* PWR_CTRL2 - 0xC590h - 150th parameter - Default 0x33h */
294 /* Change pump4 clock ratio */
295 /* -> from 1 line to 1/2 line */
296 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData19);
297 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData9);
298
299 /* GVDD/NGVDD settings */
300 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
301 DSI_IO_WriteCmd(hdsi, 2, (uint8_t *)lcdRegData5);
302
303 /* PWR_CTRL2 - 0xC590h - 149th parameter - Default 0x33h */
304 /* Rewrite the default value ! */
305 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData20);
306 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData21);
307
308 /* Panel display timing Setting 3 */
309 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData22);
310 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData23);
311
312 /* Power control 1 */
313 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData24);
314 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData25);
315
316 /* Source driver precharge */
317 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData13);
318 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData26);
319
320 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData15);
321 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData27);
322
323 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData28);
324 DSI_IO_WriteCmd(hdsi, 2, (uint8_t *)lcdRegData6);
325
326 /* GOAVST */
327 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2);
328 DSI_IO_WriteCmd(hdsi, 6, (uint8_t *)lcdRegData7);
329
330 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData29);
331 DSI_IO_WriteCmd(hdsi, 14, (uint8_t *)lcdRegData8);
332
333 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData30);
334 DSI_IO_WriteCmd(hdsi, 14, (uint8_t *)lcdRegData9);
335
336 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData31);
337 DSI_IO_WriteCmd(hdsi, 10, (uint8_t *)lcdRegData10);
338
339 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData32);
340 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData46);
341
342 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2);
343 DSI_IO_WriteCmd(hdsi, 10, (uint8_t *)lcdRegData11);
344
345 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData33);
346 DSI_IO_WriteCmd(hdsi, 15, (uint8_t *)lcdRegData12);
347
348 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData29);
349 DSI_IO_WriteCmd(hdsi, 15, (uint8_t *)lcdRegData13);
350
351 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData30);
352 DSI_IO_WriteCmd(hdsi, 10, (uint8_t *)lcdRegData14);
353
354 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData31);
355 DSI_IO_WriteCmd(hdsi, 15, (uint8_t *)lcdRegData15);
356
357 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData32);
358 DSI_IO_WriteCmd(hdsi, 15, (uint8_t *)lcdRegData16);
359
360 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData34);
361 DSI_IO_WriteCmd(hdsi, 10, (uint8_t *)lcdRegData17);
362
363 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData35);
364 DSI_IO_WriteCmd(hdsi, 10, (uint8_t *)lcdRegData18);
365
366 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData2);
367 DSI_IO_WriteCmd(hdsi, 10, (uint8_t *)lcdRegData19);
368
369 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData33);
370 DSI_IO_WriteCmd(hdsi, 15, (uint8_t *)lcdRegData20);
371
372 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData29);
373 DSI_IO_WriteCmd(hdsi, 15, (uint8_t *)lcdRegData21);
374
375 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData30);
376 DSI_IO_WriteCmd(hdsi, 10, (uint8_t *)lcdRegData22);
377
378 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData31);
379 DSI_IO_WriteCmd(hdsi, 15, (uint8_t *)lcdRegData23);
380
381 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData32);
382 DSI_IO_WriteCmd(hdsi, 15, (uint8_t *)lcdRegData24);
383
384 /////////////////////////////////////////////////////////////////////////////
385 /* PWR_CTRL1 - 0xc580h - 130th parameter - default 0x00 */
386 /* Pump 1 min and max DM */
387 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData13);
388 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData47);
389 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData48);
390 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData49);
391 /////////////////////////////////////////////////////////////////////////////
392
393 /* Exit CMD2 mode */
394 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
395 DSI_IO_WriteCmd(hdsi, 3, (uint8_t *)lcdRegData25);
396
397 /*************************************************************************** */
398 /* Standard DCS Initialization TO KEEP CAN BE DONE IN HSDT */
399 /*************************************************************************** */
400
401 /* NOP - goes back to DCS std command ? */
402 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
403
404 /* Gamma correction 2.2+ table (HSDT possible) */
405 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
406 DSI_IO_WriteCmd(hdsi, 16, (uint8_t *)lcdRegData3);
407
408 /* Gamma correction 2.2- table (HSDT possible) */
409 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
410 DSI_IO_WriteCmd(hdsi, 16, (uint8_t *)lcdRegData4);
411
412 /* Send Sleep Out command to display : no parameter */
413 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData36);
414
415 /* Wait for sleep out exit */
416 dly_tsk(120);
417
418 switch(ColorCoding){
419 case OTM8009A_FORMAT_RBG565:
420 /* Set Pixel color format to RGB565 */
421 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData37);
422 break;
423 case OTM8009A_FORMAT_RGB888:
424 /* Set Pixel color format to RGB888 */
425 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData38);
426 break;
427 default:
428 break;
429 }
430
431 /* Send command to configure display in landscape orientation mode. By default
432 the orientation mode is portrait */
433 if(orientation == OTM8009A_ORIENTATION_LANDSCAPE){
434 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData39);
435 DSI_IO_WriteCmd(hdsi, 4, (uint8_t *)lcdRegData27);
436 DSI_IO_WriteCmd(hdsi, 4, (uint8_t *)lcdRegData28);
437 }
438
439 /** CABC : Content Adaptive Backlight Control section start >> */
440 /* Note : defaut is 0 (lowest Brightness), 0xFF is highest Brightness, try 0x7F : intermediate value */
441 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData40);
442
443 /* defaut is 0, try 0x2C - Brightness Control Block, Display Dimming & BackLight on */
444 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData41);
445
446 /* defaut is 0, try 0x02 - image Content based Adaptive Brightness [Still Picture] */
447 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData42);
448
449 /* defaut is 0 (lowest Brightness), 0xFF is highest Brightness */
450 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData43);
451
452 /** CABC : Content Adaptive Backlight Control section end << */
453
454 /* Send Command Display On */
455 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData44);
456
457 /* NOP command */
458 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData1);
459
460 /* Send Command GRAM memory write (no parameters) : this initiates frame write via other DSI commands sent by */
461 /* DSI host from LTDC incoming pixels in video mode */
462 DSI_IO_WriteCmd(hdsi, 0, (uint8_t *)ShortRegData45);
463 return 0;
464}
465
466
467/*
468 * LTDC/DSI割込みハンドラ
469 */
470void ltdc_handler(void)
471{
472 ltdc_irqhandler(&hltdc_discovery);
473}
474
475void dsi_handler(void)
476{
477 dsi_irqhandler(&hdsi_discovery);
478}
479
480/*
481 * DSI/OTM8009Aスクリーンの初期化関数
482 */
483ER
484lcd_init(LCD_Handler_t *hlcd, LCD_OrientationTypeDef orientation)
485{
486 LTDC_Handle_t *hldtc = &hltdc_discovery;
487 DSI_Handle_t *hdsi = &hdsi_discovery;
488 uint32_t LcdClock = 27429; /*!< LcdClk = 27429 kHz */
489
490 uint32_t laneByteClk_kHz = 0;
491 uint32_t VSA; /*!< Vertical start active time in units of lines */
492 uint32_t VBP; /*!< Vertical Back Porch time in units of lines */
493 uint32_t VFP; /*!< Vertical Front Porch time in units of lines */
494 uint32_t VACT; /*!< Vertical Active time in units of lines = imageSize Y in pixels to display */
495 uint32_t HSA; /*!< Horizontal start active time in units of lcdClk */
496 uint32_t HBP; /*!< Horizontal Back Porch time in units of lcdClk */
497 uint32_t HFP; /*!< Horizontal Front Porch time in units of lcdClk */
498 uint32_t HACT; /*!< Horizontal Active time in units of lcdClk = imageSize X in pixels to display */
499
500 /* Toggle Hardware Reset of the DSI LCD using
501 * its XRES signal (active low) */
502 lcd_reset(hlcd);
503 hlcd->layer = LTDC_ACTIVE_LAYER_BACKGROUND;
504
505 /* Call first MSP Initialize only in case of first initialization
506 * This will set IP blocks LTDC, DSI and DMA2D
507 * - out of reset
508 * - clocked
509 * - NVIC IRQ related to IP blocks enabled
510 */
511 /** @brief Enable the LTDC clock */
512 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_LTDCEN);
513
514
515 /** @brief Toggle Sw reset of LTDC IP */
516 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_LTDCRST);
517 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_LTDCRST);
518
519 /** @brief Enable the DMA2D clock */
520 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2DEN);
521
522 /** @brief Toggle Sw reset of DMA2D IP */
523 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1RSTR), RCC_AHB1RSTR_DMA2DRST);
524 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1RSTR), RCC_AHB1RSTR_DMA2DRST);
525
526 /** @brief Enable DSI Host and wrapper clocks */
527 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_DSIEN);
528
529 /** @brief Soft Reset the DSI Host and wrapper */
530 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_DSIRST);
531 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_DSIRST);
532
533/*************************DSI Initialization***********************************/
534
535 /* Base address of DSI Host/Wrapper registers to be set before calling De-Init */
536 hlcd->hdsi = hdsi;
537 hdsi->base = TADR_DSI_BASE;
538
539 dsi_deinit(hlcd->hdsi);
540
541 hdsi->Init.pllndiv = 100;
542 hdsi->Init.pllidf = DSI_PLL_IN_DIV5;
543 hdsi->Init.pllodf = DSI_PLL_OUT_DIV1;
544 laneByteClk_kHz = 62500; /* 500 MHz / 8 = 62.5 MHz = 62500 kHz */
545
546 /* Set number of Lanes */
547 hdsi->Init.NumberOfLanes = DSI_TWO_DATA_LANES;
548
549 /* TXEscapeCkdiv = f(LaneByteClk)/15.62 = 4 */
550 hdsi->Init.TXEscapeCkdiv = laneByteClk_kHz/15620;
551
552 dsi_init(hlcd->hdsi);
553
554 /* Timing parameters for all Video modes
555 * Set Timing parameters of LTDC depending on its chosen orientation
556 */
557 if(orientation == LCD_ORIENTATION_PORTRAIT){
558 hlcd->_width = OTM8009A_480X800_WIDTH; /* 480 */
559 hlcd->_height = OTM8009A_480X800_HEIGHT; /* 800 */
560 }
561 else{
562 /* lcd_orientation == LCD_ORIENTATION_LANDSCAPE */
563 hlcd->_width = OTM8009A_800X480_WIDTH; /* 800 */
564 hlcd->_height = OTM8009A_800X480_HEIGHT; /* 480 */
565 }
566
567 HACT = hlcd->_width;
568 VACT = hlcd->_height;
569
570 /* The following values are same for portrait and landscape orientations */
571 VSA = OTM8009A_480X800_VSYNC; /* 12 */
572 VBP = OTM8009A_480X800_VBP; /* 12 */
573 VFP = OTM8009A_480X800_VFP; /* 12 */
574 HSA = OTM8009A_480X800_HSYNC; /* 63 */
575 HBP = OTM8009A_480X800_HBP; /* 120 */
576 HFP = OTM8009A_480X800_HFP; /* 120 */
577
578 hlcd->dsivc.VirtualChannelID = LCD_OTM8009A_ID;
579 hlcd->dsivc.ColorCoding = LCD_DSI_PIXEL_DATA_FMT_RBG888;
580 hlcd->dsivc.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
581 hlcd->dsivc.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
582 hlcd->dsivc.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
583 hlcd->dsivc.Mode = DSI_VID_MODE_BURST; /* Mode Video burst ie : one LgP per line */
584 hlcd->dsivc.NullPacketSize = 0xFFF;
585 hlcd->dsivc.NumberOfChunks = 0;
586 hlcd->dsivc.PacketSize = HACT; /* Value depending on display orientation choice portrait/landscape */
587 hlcd->dsivc.HorizontalSyncActive = (HSA * laneByteClk_kHz)/LcdClock;
588 hlcd->dsivc.HorizontalBackPorch = (HBP * laneByteClk_kHz)/LcdClock;
589 hlcd->dsivc.HorizontalLine = ((HACT + HSA + HBP + HFP) * laneByteClk_kHz)/LcdClock; /* Value depending on display orientation choice portrait/landscape */
590 hlcd->dsivc.VerticalSyncActive = VSA;
591 hlcd->dsivc.VerticalBackPorch = VBP;
592 hlcd->dsivc.VerticalFrontPorch = VFP;
593 hlcd->dsivc.VerticalActive = VACT; /* Value depending on display orientation choice portrait/landscape */
594
595 /* Enable or disable sending LP command while streaming is active in video mode */
596 hlcd->dsivc.LPCommandEnable = DSI_LP_COMMAND_ENABLE; /* Enable sending commands in mode LP (Low Power) */
597
598 /* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */
599 /* Only useful when sending LP packets is allowed while streaming is active in video mode */
600 hlcd->dsivc.LPLargestPacketSize = 16;
601
602 /* Largest packet size possible to transmit in LP mode in HFP region during VACT period */
603 /* Only useful when sending LP packets is allowed while streaming is active in video mode */
604 hlcd->dsivc.LPVACTLargestPacketSize = 0;
605
606 /* Specify for each region of the video frame, if the transmission of command in LP mode is allowed in this region */
607 /* while streaming is active in video mode */
608 hlcd->dsivc.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE; /* Allow sending LP commands during HFP period */
609 hlcd->dsivc.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE; /* Allow sending LP commands during HBP period */
610 hlcd->dsivc.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE; /* Allow sending LP commands during VACT period */
611 hlcd->dsivc.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE; /* Allow sending LP commands during VFP period */
612 hlcd->dsivc.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE; /* Allow sending LP commands during VBP period */
613 hlcd->dsivc.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE; /* Allow sending LP commands during VSync = VSA period */
614
615 /* Configure DSI Video mode timings with settings set above */
616 dsi_configvideo(hlcd->hdsi, &hlcd->dsivc);
617
618/*************************End DSI Initialization*******************************/
619
620
621/************************LTDC Initialization***********************************/
622
623 /* Timing Configuration */
624 hldtc->Init.HorizontalSync = (HSA - 1);
625 hldtc->Init.AccumulatedHBP = (HSA + HBP - 1);
626 hldtc->Init.AccumulatedActiveW = (hlcd->_width + HSA + HBP - 1);
627 hldtc->Init.TotalWidth = (hlcd->_width + HSA + HBP + HFP - 1);
628
629 /* Initialize the LCD pixel width and pixel height */
630 hldtc->LayerCfg->ImageWidth = hlcd->_width;
631 hldtc->LayerCfg->ImageHeight = hlcd->_height;
632
633 /** LCD clock configuration
634 * Note: The following values should not be changed as the PLLSAI is also used
635 * to clock the USB FS
636 * PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz
637 * PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 384 Mhz
638 * PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 384 MHz / 7 = 54.85 MHz
639 * LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_2 = 54.85 MHz / 2 = 27.429 MHz
640 */
641 /* Background value */
642 hldtc->Init.Backcolor.Blue = 0;
643 hldtc->Init.Backcolor.Green = 0;
644 hldtc->Init.Backcolor.Red = 0;
645 hldtc->Init.PCPolarity = LTDC_PCPOLARITY_IPC;
646 hldtc->Init.pllsain = 384;
647 hldtc->Init.pllsair = 7;
648 hldtc->Init.saidivr = RCC_PLLSAIDIVR_2;
649 hldtc->base = TADR_LTDC_BASE;
650
651 /* Get LTDC Configuration from DSI Configuration */
652 dci_configltdc(hldtc, &hlcd->dsivc);
653
654 /* Initialize the LTDC */
655 ltdc_init(hldtc);
656 hlcd->hltdc = hldtc;
657
658 /* Enable the DSI host and wrapper after the LTDC initialization
659 To avoid any synchronization issue, the DSI shall be started after enabling the LTDC */
660 dsi_start(hlcd->hdsi);
661
662 /* Initialize the font */
663// BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
664
665/************************End LTDC Initialization*******************************/
666
667
668/***********************OTM8009A Initialization********************************/
669
670 /* Initialize the OTM8009A LCD Display IC Driver (KoD LCD IC Driver)
671 * depending on configuration set in 'hdsivideo_handle'.
672 */
673 OTM8009A_Init(hlcd->hdsi, OTM8009A_FORMAT_RGB888, orientation);
674
675/***********************End OTM8009A Initialization****************************/
676 return E_OK;
677}
678
679/*
680 * DSI/OTM8009Aスクリーンのリセット関数
681 */
682ER
683lcd_reset(LCD_Handler_t *hlcd)
684{
685 GPIO_Init_t gpio_init_structure;
686 uint32_t base = TADR_GPIOJ_BASE;
687
688 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOJEN);
689
690 /* Configure the GPIO on PJ15 */
691 gpio_init_structure.mode = GPIO_MODE_OUTPUT;
692 gpio_init_structure.pull = GPIO_PULLUP;
693 gpio_init_structure.otype = GPIO_OTYPE_PP;
694 gpio_init_structure.speed = GPIO_SPEED_HIGH;
695 gpio_setup(base, &gpio_init_structure, PINPOSITION15);
696
697 sil_wrw_mem((uint32_t *)(base+TOFF_GPIO_BSRR), GPIO_PIN_15<<16);
698 sil_dly_nse(100);
699
700 dly_tsk(20); /* wait 20 ms */
701
702 /* Desactivate XRES */
703 sil_wrw_mem((uint32_t *)(base+TOFF_GPIO_BSRR), GPIO_PIN_15);
704
705 /* Wait for 10ms after releasing XRES before sending commands */
706 dly_tsk(10);
707 return E_OK;
708}
709
710
711/*
712 * DSI/OTM8009Aスクリーンレイヤ初期化関数
713 */
714ER
715lcd_layerdefaultinit(LCD_Handler_t *hlcd, LCD_DrawProp_t *pDrawProp, uint16_t LayerIndex, uint32_t FB_Address)
716{
717 LTDC_LayerCfg_t Layercfg;
718
719 /* Layer Init */
720 Layercfg.WindowX0 = 0;
721 Layercfg.WindowX1 = hlcd->_width;
722 Layercfg.WindowY0 = 0;
723 Layercfg.WindowY1 = hlcd->_height;
724 Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
725 Layercfg.FBStartAdress = FB_Address;
726 Layercfg.Alpha = 255;
727 Layercfg.Alpha0 = 0;
728 Layercfg.Backcolor.Blue = 0;
729 Layercfg.Backcolor.Green = 0;
730 Layercfg.Backcolor.Red = 0;
731 Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
732 Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
733 Layercfg.ImageWidth = hlcd->_width;
734 Layercfg.ImageHeight = hlcd->_height;
735
736 ltdc_configlayer(hlcd->hltdc, &Layercfg, LayerIndex);
737
738 hlcd->layer = LayerIndex;
739 pDrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;
740 pDrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK;
741 pDrawProp[LayerIndex].hlcd = hlcd;
742 return E_OK;
743}
744
745/*
746 * DSI/OTM8009Aスクリーンレイヤ表示設定関数
747 */
748void
749lcd_setlayervisible(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t State)
750{
751 uint32_t layer = (TADR_LTDC_LAYER1 + (LTDC_WINDOW_SIZE * LayerIndex));
752 if(State == 1){
753 sil_orw_mem((uint32_t *)(layer+TOFF_LTDCW_CR), LTDC_CR_LEN);
754 }
755 else{
756 sil_andw_mem((uint32_t *)(layer+TOFF_LTDCW_CR), LTDC_CR_LEN);
757 }
758 sil_orw_mem((uint32_t *)(TADR_LTDC_BASE+TOFF_LTDC_SRCR), LTDC_SRCR_IMR);
759}
760
761/*
762 * DSI/OTM8009Aスクリーンレイヤ透過設定関数
763 */
764void
765lcd_settransparency(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint8_t Transparency)
766{
767 ltdc_setalpha(hlcd->hltdc, Transparency, LayerIndex);
768}
769
770/*
771 * DSI/OTM8009AスクリーンレイヤRAMアドレス設定関数
772 */
773void
774lcd_setlayeraddress(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t Address)
775{
776 ltdc_setaddress(hlcd->hltdc, Address, LayerIndex);
777}
778
779/*
780 * DSI/OTM8009A表示ウィンドウ設定
781 */
782void
783lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
784{
785 /* Reconfigure the layer size */
786 ltdc_setwindowsize(hlcd->hltdc, Width, Height, LayerIndex);
787
788 /* Reconfigure the layer position */
789 ltdc_setwindowposition(hlcd->hltdc, Xpos, Ypos, LayerIndex);
790}
791
792/**
793 * @brief Configures and sets the color keying.
794 * @param LayerIndex: Layer foreground or background
795 * @param RGBValue: Color reference
796 */
797void
798lcd_setcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex, uint32_t RGBValue)
799{
800 /* Configure and Enable the color Keying for LCD Layer */
801 ltdc_configcolorkeying(hlcd->hltdc, RGBValue, LayerIndex);
802 ltdc_enablecolorkeying(hlcd->hltdc, LayerIndex);
803}
804
805/**
806 * @brief Disables the color keying.
807 * @param LayerIndex: Layer foreground or background
808 */
809void
810lcd_resetcolorkeying(LCD_Handler_t *hlcd, uint32_t LayerIndex)
811{
812 /* Disable the color Keying for LCD Layer */
813 ltdc_disablecolorkeying(hlcd->hltdc, LayerIndex);
814}
815
816/*
817 * DSI/OTM8009Aスクリーンクリア
818 */
819void
820lcd_clear(LCD_Handler_t *hlcd, uint32_t Color)
821{
822 /* Clear the LCD */
823 LL_FillBuffer(hlcd->layer, (uint32_t *)(hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress), hlcd->_width, hlcd->_height, 0, Color);
824}
825
826/*
827 * PIXEL読み出し
828 * param1 hlcd: Pointer to LCD Handler
829 * param2 x: X position
830 * param3 y: Y position
831 */
832uint32_t
833lcd_readPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos)
834{
835 LTDC_Handle_t *hltdc = hlcd->hltdc;
836 uint32_t ret = 0;
837
838 if(hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888){
839 /* Read data value from SDRAM memory */
840 ret = *(volatile uint32_t*)(hltdc->LayerCfg[hlcd->layer].FBStartAdress + (2*(Ypos*hlcd->_width + Xpos)));
841 }
842 else if(hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888){
843 /* Read data value from SDRAM memory */
844 ret = (*(volatile uint32_t*) (hltdc->LayerCfg[hlcd->layer].FBStartAdress + (2*(Ypos*hlcd->_width + Xpos))) & 0x00FFFFFF);
845 }
846 else if((hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
847 (hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
848 (hltdc->LayerCfg[hlcd->layer].PixelFormat == LTDC_PIXEL_FORMAT_AL88)){
849 /* Read data value from SDRAM memory */
850 ret = *(volatile uint16_t*) (hltdc->LayerCfg[hlcd->layer].FBStartAdress + (2*(Ypos*hlcd->_width + Xpos)));
851 }
852 else{
853 /* Read data value from SDRAM memory */
854 ret = *(volatile uint8_t*) (hltdc->LayerCfg[hlcd->layer].FBStartAdress + (2*(Ypos*hlcd->_width + Xpos)));
855 }
856 return ret;
857}
858
859/*
860 * PIXEL描画
861 * param1 hlcd: Pointer to LCD Handler
862 * param2 x: X position
863 * param3 y: Y position
864 * param4 color: color value
865 */
866void
867lcd_drawPixel(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code)
868{
869 /* Write data value to all SDRAM memory */
870 *(volatile uint32_t*) (hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress + (4*(Ypos*hlcd->_width + Xpos))) = RGB_Code;
871}
872
873/*
874 * 垂直方向LINEの高速描画
875 * param1 hlcd: Pointer to LCD Handler
876 * param2 x: start X position
877 * param3 y: start Y position
878 * param4 h: height
879 * param5 color: color value
880 */
881void
882lcd_drawFastHLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color)
883{
884 uint32_t Xaddress = 0;
885
886 /* Get the line address */
887 Xaddress = (hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress) + 4*(hlcd->_width*Ypos + Xpos);
888
889 /* Write line */
890 LL_FillBuffer(hlcd->layer, (uint32_t *)Xaddress, Length, 1, 0, color);
891}
892
893/*
894 * 水平方向LINEの高速描画
895 * param1 hlcd: Pointer to LCD Handler
896 * param2 x: start X position
897 * param3 y: start Y position
898 * param4 w: width
899 * param5 color: color value
900 */
901void
902lcd_drawFastVLine(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint32_t color)
903{
904 uint32_t Xaddress = 0;
905
906 /* Get the line address */
907 Xaddress = (hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress) + 4*(hlcd->_width*Ypos + Xpos);
908
909 /* Write line */
910 LL_FillBuffer(hlcd->layer, (uint32_t *)Xaddress, 1, Length, (hlcd->_width - 1), color);
911}
912
913/*
914 * BITMAP描画
915 * param1 hlcd: Pointer to LCD Handler
916 * param2 x0: Bmp X position in the LCD
917 * param3 y0: Bmp Y position in the LCD
918 * param4 pbmp: Pointer to Bmp picture address in the internal Flash
919 */
920void
921lcd_drawBitmap(LCD_Handler_t *hlcd, uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp)
922{
923 uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
924 uint32_t Address;
925 uint32_t InputColorMode = 0;
926
927 /* Get bitmap data address offset */
928 index = *(volatile uint16_t *) (pbmp + 10);
929 index |= (*(volatile uint16_t *) (pbmp + 12)) << 16;
930
931 /* Read bitmap width */
932 width = *(volatile uint16_t *) (pbmp + 18);
933 width |= (*(volatile uint16_t *) (pbmp + 20)) << 16;
934
935 /* Read bitmap height */
936 height = *(volatile uint16_t *) (pbmp + 22);
937 height |= (*(volatile uint16_t *) (pbmp + 24)) << 16;
938
939 /* Read bit/pixel */
940 bit_pixel = *(uint16_t *) (pbmp + 28);
941
942 /* Set the address */
943 Address = hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress + (((hlcd->_width*Ypos) + Xpos)*(4));
944
945 /* Get the layer pixel format */
946 if((bit_pixel/8) == 4){
947 InputColorMode = DMA2D_ARGB8888;
948 }
949 else if((bit_pixel/8) == 2){
950 InputColorMode = DMA2D_RGB565;
951 }
952 else{
953 InputColorMode = DMA2D_RGB888;
954 }
955
956 /* Bypass the bitmap header */
957 pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
958
959 /* Convert picture to ARGB8888 pixel format */
960 for(index=0; index < height; index++){
961 /* Pixel format conversion */
962 LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)Address, width, InputColorMode);
963
964 /* Increment the source and destination buffers */
965 Address+= (hlcd->_width*4);
966 pbmp -= width*(bit_pixel/8);
967 }
968}
969
970/*
971 * 表示オン
972 * param1 hlcd: Pointer to LCD Handler
973 */
974void
975lcd_displayOn(LCD_Handler_t *hlcd)
976{
977 /* Send Display on DCS command to display */
978 dsi_swrite(hlcd->hdsi, hlcd->dsivc.VirtualChannelID,
979 DSI_DCS_SHORT_PKT_WRITE_P1,
980 OTM8009A_CMD_DISPON,
981 0x00);
982}
983
984/*
985 * 表示オフ
986 * param1 hlcd: Pointer to LCD Handler
987 */
988void
989lcd_displayOff(LCD_Handler_t *hlcd)
990{
991 /* Send Display off DCS Command to display */
992 dsi_swrite(hlcd->hdsi, hlcd->dsivc.VirtualChannelID,
993 DSI_DCS_SHORT_PKT_WRITE_P1,
994 OTM8009A_CMD_DISPOFF,
995 0x00);
996}
997
998/**
999 * @brief Set the brightness value
1000 * @param BrightnessValue: [00: Min (black), 100 Max]
1001 */
1002void
1003lcd_setbrightness(LCD_Handler_t *hlcd, uint8_t BrightnessValue)
1004{
1005 /* Send Display on DCS command to display */
1006 dsi_swrite(hlcd->hdsi, LCD_OTM8009A_ID,
1007 DSI_DCS_SHORT_PKT_WRITE_P1,
1008 OTM8009A_CMD_WRDISBV, (uint16_t)(BrightnessValue * 255)/100);
1009}
1010
1011/*
1012 * RECTANGLE塗りつぶし描画
1013 * param1 hlcd: Pointer to LCD Handler
1014 * param2 x: left X position
1015 * param3 y: top Y position
1016 * param4 w: width
1017 * param5 h: height
1018 * param6 color: color value
1019 */
1020void
1021lcd_fillRect(LCD_Handler_t *hlcd, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint32_t color)
1022{
1023 uint32_t Xaddress = 0;
1024
1025 /* Get the rectangle start address */
1026 Xaddress = (hlcd->hltdc->LayerCfg[hlcd->layer].FBStartAdress) + 4*(hlcd->_width*Ypos + Xpos);
1027
1028 /* Fill the rectangle */
1029 LL_FillBuffer(hlcd->layer, (uint32_t *)Xaddress, Width, Height, (hlcd->_width - Width), color);
1030}
1031
1032
1033/*
1034 * 線描画
1035 * param1 pDrawProp: Pointer to Draw Prop
1036 * param2 x1: Point 1 X position
1037 * param3 y1: Point 1 Y position
1038 * param4 x2: Point 2 X position
1039 * param5 y2: Point 2 Y position
1040 */
1041void
1042lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
1043{
1044 LCD_Handler_t *hlcd = pDrawProp->hlcd;
1045 int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
1046 yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
1047 curpixel = 0;
1048
1049 deltax = ABS(x2 - x1); /* The difference between the x's */
1050 deltay = ABS(y2 - y1); /* The difference between the y's */
1051 x = x1; /* Start x off at the first pixel */
1052 y = y1; /* Start y off at the first pixel */
1053
1054 if(x2 >= x1){ /* The x-values are increasing */
1055 xinc1 = 1;
1056 xinc2 = 1;
1057 }
1058 else{ /* The x-values are decreasing */
1059 xinc1 = -1;
1060 xinc2 = -1;
1061 }
1062
1063 if(y2 >= y1){ /* The y-values are increasing */
1064 yinc1 = 1;
1065 yinc2 = 1;
1066 }
1067 else{ /* The y-values are decreasing */
1068 yinc1 = -1;
1069 yinc2 = -1;
1070 }
1071
1072 if(deltax >= deltay){ /* There is at least one x-value for every y-value */
1073 xinc1 = 0; /* Don't change the x when numerator >= denominator */
1074 yinc2 = 0; /* Don't change the y for every iteration */
1075 den = deltax;
1076 num = deltax / 2;
1077 numadd = deltay;
1078 numpixels = deltax; /* There are more x-values than y-values */
1079 }
1080 else{ /* There is at least one y-value for every x-value */
1081 xinc2 = 0; /* Don't change the x for every iteration */
1082 yinc1 = 0; /* Don't change the y when numerator >= denominator */
1083 den = deltay;
1084 num = deltay / 2;
1085 numadd = deltax;
1086 numpixels = deltay; /* There are more y-values than x-values */
1087 }
1088
1089 for(curpixel = 0; curpixel <= numpixels; curpixel++){
1090 lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor); /* Draw the current pixel */
1091 num += numadd; /* Increase the numerator by the top of the fraction */
1092 if(num >= den){ /* Check if numerator >= denominator */
1093 num -= den; /* Calculate the new numerator value */
1094 x += xinc1; /* Change the x as appropriate */
1095 y += yinc1; /* Change the y as appropriate */
1096 }
1097 x += xinc2; /* Change the x as appropriate */
1098 y += yinc2; /* Change the y as appropriate */
1099 }
1100}
1101
1102/*
1103 * RECTANGLE描画
1104 * param1 pDrawProp: Pointer to Draw Prop
1105 * param2 x: left X position
1106 * param3 y: top Y position
1107 * param4 w: width
1108 * param5 h: height
1109 */
1110void
1111lcd_drawRect(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
1112{
1113 LCD_Handler_t *hlcd = pDrawProp->hlcd;
1114 uint32_t color = pDrawProp->TextColor;
1115
1116 /* Draw horizontal lines */
1117 lcd_drawFastHLine(hlcd, Xpos, Ypos, Width, color);
1118 lcd_drawFastHLine(hlcd, Xpos, (Ypos+ Height), Width, color);
1119
1120 /* Draw vertical lines */
1121 lcd_drawFastVLine(hlcd, Xpos, Ypos, Height, color);
1122 lcd_drawFastVLine(hlcd, (Xpos + Width), Ypos, Height, color);
1123}
1124
1125/*
1126 * 円描画
1127 * param1 pDrawProp: Pointer to Draw Prop
1128 * param2 x0: X position
1129 * param3 y0: Y position
1130 * param4 Radius: Circle radius
1131 */
1132void
1133lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
1134{
1135 LCD_Handler_t *hlcd = pDrawProp->hlcd;
1136 uint32_t color = pDrawProp->TextColor;
1137 int32_t D; /* Decision Variable */
1138 uint32_t CurX; /* Current X Value */
1139 uint32_t CurY; /* Current Y Value */
1140
1141 D = 3 - (Radius << 1);
1142 CurX = 0;
1143 CurY = Radius;
1144
1145 while (CurX <= CurY){
1146 lcd_drawPixel(hlcd, (Xpos + CurX), (Ypos - CurY), color);
1147 lcd_drawPixel(hlcd, (Xpos - CurX), (Ypos - CurY), color);
1148 lcd_drawPixel(hlcd, (Xpos + CurY), (Ypos - CurX), color);
1149 lcd_drawPixel(hlcd, (Xpos - CurY), (Ypos - CurX), color);
1150 lcd_drawPixel(hlcd, (Xpos + CurX), (Ypos + CurY), color);
1151 lcd_drawPixel(hlcd, (Xpos - CurX), (Ypos + CurY), color);
1152 lcd_drawPixel(hlcd, (Xpos + CurY), (Ypos + CurX), color);
1153 lcd_drawPixel(hlcd, (Xpos - CurY), (Ypos + CurX), color);
1154 if(D < 0){
1155 D += (CurX << 2) + 6;
1156 }
1157 else{
1158 D += ((CurX - CurY) << 2) + 10;
1159 CurY--;
1160 }
1161 CurX++;
1162 }
1163}
1164
1165/*
1166 * 楕円描画
1167 * param1 pDrawProp: Pointer to Draw Prop
1168 * param2 x0: X position
1169 * param3 y0: Y position
1170 * param4 XRadius: Ellipse X radius
1171 * param5 YRadius: Ellipse Y radius
1172 */
1173void
1174lcd_DrawEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius)
1175{
1176 LCD_Handler_t *hlcd = pDrawProp->hlcd;
1177 uint32_t color = pDrawProp->TextColor;
1178 int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
1179 float K = 0, rad1 = 0, rad2 = 0;
1180
1181 rad1 = XRadius;
1182 rad2 = YRadius;
1183
1184 K = (float)(rad2/rad1);
1185
1186 do{
1187 lcd_drawPixel(hlcd, (Xpos-(uint16_t)(x/K)), (Ypos+y), color);
1188 lcd_drawPixel(hlcd, (Xpos+(uint16_t)(x/K)), (Ypos+y), color);
1189 lcd_drawPixel(hlcd, (Xpos+(uint16_t)(x/K)), (Ypos-y), color);
1190 lcd_drawPixel(hlcd, (Xpos-(uint16_t)(x/K)), (Ypos-y), color);
1191
1192 e2 = err;
1193 if(e2 <= x){
1194 err += ++x*2+1;
1195 if (-y == x && e2 <= y)
1196 e2 = 0;
1197 }
1198 if(e2 > y)
1199 err += ++y*2+1;
1200 }while (y <= 0);
1201}
1202
1203/*
1204 * PLOY-LINE描画
1205 * param1 pDrawProp: Pointer to Draw Prop
1206 * param2 Points: Pointer to the points array
1207 * param3 PointCount: Number of points
1208 */
1209void
1210lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
1211{
1212 int16_t X = 0, Y = 0;
1213
1214 if(PointCount < 2){
1215 return;
1216 }
1217
1218 lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
1219
1220 while(--PointCount){
1221 X = Points->X;
1222 Y = Points->Y;
1223 Points++;
1224 lcd_drawLine(pDrawProp, X, Y, Points->X, Points->Y);
1225 }
1226}
1227
1228/*
1229 * 円塗りつぶし描画
1230 * param1 pDrawProp: Pointer to Draw Prop
1231 * param2 x0: X position
1232 * param3 y0: Y position
1233 * param4 Radius: Circle radius
1234 */
1235void
1236lcd_fillCircle(LCD_DrawProp_t *pDrawProp, uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
1237{
1238 LCD_Handler_t *hlcd = pDrawProp->hlcd;
1239 uint32_t color = pDrawProp->TextColor;
1240 int32_t D; /* Decision Variable */
1241 uint32_t CurX; /* Current X Value */
1242 uint32_t CurY; /* Current Y Value */
1243
1244 D = 3 - (Radius << 1);
1245
1246 CurX = 0;
1247 CurY = Radius;
1248
1249 while (CurX <= CurY){
1250 if(CurY > 0){
1251 lcd_drawFastHLine(hlcd, Xpos - CurY, Ypos + CurX, 2*CurY, color);
1252 lcd_drawFastHLine(hlcd, Xpos - CurY, Ypos - CurX, 2*CurY, color);
1253 }
1254
1255 if(CurX > 0){
1256 lcd_drawFastHLine(hlcd, Xpos - CurX, Ypos - CurY, 2*CurX, color);
1257 lcd_drawFastHLine(hlcd, Xpos - CurX, Ypos + CurY, 2*CurX, color);
1258 }
1259 if(D < 0){
1260 D += (CurX << 2) + 6;
1261 }
1262 else{
1263 D += ((CurX - CurY) << 2) + 10;
1264 CurY--;
1265 }
1266 CurX++;
1267 }
1268
1269 lcd_DrawCircle(pDrawProp, Xpos, Ypos, Radius);
1270}
1271
1272/*
1273 * 楕円塗りつぶし描画
1274 * param1 pDrawProp: Pointer to Draw Prop
1275 * param2 x0: X position
1276 * param3 y0: Y position
1277 * param4 XRadius: Ellipse X radius
1278 * param5 YRadius: Ellipse Y radius
1279 */
1280void
1281lcd_fillEllipse(LCD_DrawProp_t *pDrawProp, int Xpos, int Ypos, int XRadius, int YRadius)
1282{
1283 LCD_Handler_t *hlcd = pDrawProp->hlcd;
1284 int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
1285 float K = 0, rad1 = 0, rad2 = 0;
1286
1287 rad1 = XRadius;
1288 rad2 = YRadius;
1289
1290 K = (float)(rad2/rad1);
1291
1292 do{
1293 lcd_drawFastHLine(hlcd, (Xpos-(uint16_t)(x/K)), (Ypos+y), (2*(uint16_t)(x/K) + 1), pDrawProp->TextColor);
1294 lcd_drawFastHLine(hlcd, (Xpos-(uint16_t)(x/K)), (Ypos-y), (2*(uint16_t)(x/K) + 1), pDrawProp->TextColor);
1295
1296 e2 = err;
1297 if(e2 <= x){
1298 err += ++x*2+1;
1299 if (-y == x && e2 <= y)
1300 e2 = 0;
1301 }
1302 if(e2 > y)
1303 err += ++y*2+1;
1304 }while (y <= 0);
1305}
1306
1307/*
1308 * PLOY-LINE塗りつぶし描画
1309 * param1 pDrawProp: Pointer to Draw Prop
1310 * param2 Points: Pointer to the points array
1311 * param3 PointCount: Number of points
1312 */
1313void
1314lcd_fillPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
1315{
1316 int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0;
1317 uint16_t IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0;
1318
1319 IMAGE_LEFT = IMAGE_RIGHT = Points->X;
1320 IMAGE_TOP= IMAGE_BOTTOM = Points->Y;
1321
1322 for(counter = 1; counter < PointCount; counter++){
1323 pixelX = POLY_X(counter);
1324 if(pixelX < IMAGE_LEFT){
1325 IMAGE_LEFT = pixelX;
1326 }
1327 if(pixelX > IMAGE_RIGHT){
1328 IMAGE_RIGHT = pixelX;
1329 }
1330
1331 pixelY = POLY_Y(counter);
1332 if(pixelY < IMAGE_TOP){
1333 IMAGE_TOP = pixelY;
1334 }
1335 if(pixelY > IMAGE_BOTTOM){
1336 IMAGE_BOTTOM = pixelY;
1337 }
1338 }
1339
1340 if(PointCount < 2){
1341 return;
1342 }
1343
1344 X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2;
1345 Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2;
1346
1347 X_first = Points->X;
1348 Y_first = Points->Y;
1349
1350 while(--PointCount){
1351 X = Points->X;
1352 Y = Points->Y;
1353 Points++;
1354 X2 = Points->X;
1355 Y2 = Points->Y;
1356
1357 FillTriangle(pDrawProp, X, X2, X_center, Y, Y2, Y_center);
1358 FillTriangle(pDrawProp, X, X_center, X2, Y, Y_center, Y2);
1359 FillTriangle(pDrawProp, X_center, X2, X, Y_center, Y2, Y);
1360 }
1361
1362 FillTriangle(pDrawProp, X_first, X2, X_center, Y_first, Y2, Y_center);
1363 FillTriangle(pDrawProp, X_first, X_center, X2, Y_first, Y_center, Y2);
1364 FillTriangle(pDrawProp, X_center, X2, X_first, Y_center, Y2, Y_first);
1365}
1366
1367/*******************************************************************************
1368 LTDC, DMA2D and DSI BSP Routines
1369*******************************************************************************/
1370
1371/*
1372 * トライアングルフィル
1373 * param1 pDrawProp: Pointer to Draw Prop
1374 * param2 x1: 点1 X座標始点
1375 * param3 y1: 点1 Y座標始点
1376 * param4 x2: 点2 X座標始点
1377 * param5 y2: 点2 Y座標始点
1378 * param6 x3: 点3 X座標始点
1379 * param7 y3: 点3 Y座標始点
1380 */
1381static void
1382FillTriangle(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3)
1383{
1384 int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
1385 yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
1386 curpixel = 0;
1387
1388 deltax = ABS(x2 - x1); /* The difference between the x's */
1389 deltay = ABS(y2 - y1); /* The difference between the y's */
1390 x = x1; /* Start x off at the first pixel */
1391 y = y1; /* Start y off at the first pixel */
1392
1393 if(x2 >= x1){ /* The x-values are increasing */
1394 xinc1 = 1;
1395 xinc2 = 1;
1396 }
1397 else{ /* The x-values are decreasing */
1398 xinc1 = -1;
1399 xinc2 = -1;
1400 }
1401
1402 if(y2 >= y1){ /* The y-values are increasing */
1403 yinc1 = 1;
1404 yinc2 = 1;
1405 }
1406 else{ /* The y-values are decreasing */
1407 yinc1 = -1;
1408 yinc2 = -1;
1409 }
1410
1411 if(deltax >= deltay){ /* There is at least one x-value for every y-value */
1412 xinc1 = 0; /* Don't change the x when numerator >= denominator */
1413 yinc2 = 0; /* Don't change the y for every iteration */
1414 den = deltax;
1415 num = deltax / 2;
1416 numadd = deltay;
1417 numpixels = deltax; /* There are more x-values than y-values */
1418 }
1419 else{ /* There is at least one y-value for every x-value */
1420 xinc2 = 0; /* Don't change the x for every iteration */
1421 yinc1 = 0; /* Don't change the y when numerator >= denominator */
1422 den = deltay;
1423 num = deltay / 2;
1424 numadd = deltax;
1425 numpixels = deltay; /* There are more y-values than x-values */
1426 }
1427
1428 for(curpixel = 0; curpixel <= numpixels; curpixel++){
1429 lcd_drawLine(pDrawProp, x, y, x3, y3);
1430
1431 num += numadd; /* Increase the numerator by the top of the fraction */
1432 if(num >= den){ /* Check if numerator >= denominator */
1433 num -= den; /* Calculate the new numerator value */
1434 x += xinc1; /* Change the x as appropriate */
1435 y += yinc1; /* Change the y as appropriate */
1436 }
1437 x += xinc2; /* Change the x as appropriate */
1438 y += yinc2; /* Change the y as appropriate */
1439 }
1440}
1441
1442/*
1443 * バッファフィル
1444 * param1 hlcd: Pointer to LCD Handler
1445 * param2 pDst:バッファ先頭ポインタ
1446 * param3 xSize: バッファ幅
1447 * param3 ySize: バッファ高さ
1448 * param4 OffLine: 出力オフセット
1449 * param5 ColorIndex: フィルカラー
1450 */
1451static
1452void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex)
1453{
1454 /* Register to memory mode with ARGB8888 as color Mode */
1455 hdma2d_discovery.Init.Mode = DMA2D_R2M;
1456 hdma2d_discovery.Init.ColorMode = CM_ARGB8888;
1457 hdma2d_discovery.Init.OutputOffset = OffLine;
1458
1459 hdma2d_discovery.base = TADR_DMA2D_BASE;
1460
1461 /* DMA2D Initialization */
1462 if(dma2d_init(&hdma2d_discovery) == E_OK){
1463 if(dma2d_configlayer(&hdma2d_discovery, LayerIndex) == E_OK){
1464 if(dma2d_start(&hdma2d_discovery, ColorIndex, (uint32_t)pDst, xSize, ySize) == E_OK){
1465 /* Polling For DMA transfer */
1466 dma2d_waittransfar(&hdma2d_discovery, 10);
1467 }
1468 }
1469 }
1470}
1471
1472/**
1473 * @brief Converts a line to an ARGB8888 pixel format.
1474 * @param pSrc: Pointer to source buffer
1475 * @param pDst: Output color
1476 * @param xSize: Buffer width
1477 * @param ColorMode: Input color mode
1478 */
1479static
1480void LL_ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode)
1481{
1482 /* Configure the DMA2D Mode, Color Mode and output offset */
1483 hdma2d_discovery.Init.Mode = DMA2D_M2M_PFC;
1484 hdma2d_discovery.Init.ColorMode = CM_ARGB8888;
1485 hdma2d_discovery.Init.OutputOffset = 0;
1486
1487 /* Foreground Configuration */
1488 hdma2d_discovery.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
1489 hdma2d_discovery.LayerCfg[1].InputAlpha = 0xFF;
1490 hdma2d_discovery.LayerCfg[1].InputColorMode = ColorMode;
1491 hdma2d_discovery.LayerCfg[1].InputOffset = 0;
1492
1493 hdma2d_discovery.base = TADR_DMA2D_BASE;
1494
1495 /* DMA2D Initialization */
1496 if(dma2d_init(&hdma2d_discovery) == E_OK){
1497 if(dma2d_configlayer(&hdma2d_discovery, 1) == E_OK){
1498 if(dma2d_start(&hdma2d_discovery, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == E_OK){
1499 /* Polling For DMA transfer */
1500 dma2d_waittransfar(&hdma2d_discovery, 10);
1501 }
1502 }
1503 }
1504}
1505
Note: See TracBrowser for help on using the repository browser.