source: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/adafruit_ILI9341/adafruit_ILI9341.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: 21.9 KB
Line 
1/*
2 * TOPPERS BASE PLATFORM MIDDLEWARE
3 *
4 * Copyright (C) 2017-2019 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 * Written by Limor Fried/Ladyada for Adafruit Industries.
41 * MIT license, all text above must be included in any redistribution
42 * http://opensource.org/licenses/mit-license.php
43 */
44
45/*
46 * ADAFRUIT ILI9341 2.8"LCD制御プログラムの本体
47 */
48
49#include <kernel.h>
50#include <t_syslog.h>
51#include <t_stdlib.h>
52#include <stdio.h>
53#include <string.h>
54#include <target_syssvc.h>
55#include "syssvc/syslog.h"
56#include "device.h"
57#include "adafruit_ILI9341.h"
58
59/*
60 * サービスコールのエラーのログ出力
61 */
62Inline void
63svc_perror(const char *file, int_t line, const char *expr, ER ercd)
64{
65 if (ercd < 0) {
66 t_perror(LOG_ERROR, file, line, expr, ercd);
67 }
68}
69
70#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
71#define ABS(X) ((X) > 0 ? (X) : -(X))
72
73
74/* Buffer used for transmission */
75static uint8_t aTxBuffer[4];
76
77#define PORT_HIGH 1
78#define PORT_LOW 0
79
80#define MADCTL_MY 0x80
81#define MADCTL_MX 0x40
82#define MADCTL_MV 0x20
83#define MADCTL_ML 0x10
84#define MADCTL_RGB 0x00
85#define MADCTL_BGR 0x08
86#define MADCTL_MH 0x04
87
88
89#define cs_set(sw) digitalWrite(hlcd->cs_pin, sw)
90#define dc_set(sw) digitalWrite(hlcd->dc_pin, sw)
91#define rst_set(sw) digitalWrite(hlcd->rst_pin, sw)
92#define cs2_set(sw) digitalWrite(hlcd->cs2_pin, sw)
93
94
95/*
96 * LCDへのコマンド送信関数
97 */
98ER
99lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c)
100{
101 ER ercd = E_OK;
102
103 if(hlcd->spi_lock != 0){
104 if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
105 return ercd;
106 }
107 dc_set(PORT_LOW);
108 cs_set(PORT_LOW);
109
110 aTxBuffer[0] = c;
111#if SPI_WAIT_TIME != 0
112 ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
113#else
114 if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
115 ercd = spi_wait(hlcd->hspi, 100);
116 }
117#endif
118
119 cs_set(PORT_HIGH);
120 if(hlcd->spi_lock != 0)
121 sig_sem(hlcd->spi_lock);
122 return ercd;
123}
124
125/*
126 * LCDへのデータ送信関数
127 */
128ER
129lcd_writedata(LCD_Handler_t *hlcd, uint8_t c)
130{
131 ER ercd = E_OK;
132
133 if(hlcd->spi_lock != 0){
134 if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
135 return ercd;
136 }
137 dc_set(PORT_HIGH);
138 cs_set(PORT_LOW);
139 sil_dly_nse(100);
140
141 aTxBuffer[0] = c;
142#if SPI_WAIT_TIME != 0
143 ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
144#else
145 if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
146 ercd = spi_wait(hlcd->hspi, 100);
147 }
148#endif
149
150 sil_dly_nse(100);
151 cs_set(PORT_HIGH);
152 if(hlcd->spi_lock != 0)
153 sig_sem(hlcd->spi_lock);
154 return ercd;
155}
156
157/*
158 * LCDへの2バイトデータ送信関数
159 */
160ER
161lcd_writedata2(LCD_Handler_t *hlcd, uint16_t c, int cnt)
162{
163 ER ercd = E_OK;
164 int i;
165
166 if(cnt == 0)
167 return ercd;
168 if(hlcd->spi_lock != 0){
169 if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
170 return ercd;
171 }
172 dc_set(PORT_HIGH);
173 cs_set(PORT_LOW);
174 sil_dly_nse(100);
175 aTxBuffer[0] = c >> 8;
176 aTxBuffer[1] = (uint8_t)c;
177 for(i = 0 ; i < cnt ; i++){
178 if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
179 break;
180 }
181#if SPI_WAIT_TIME == 0
182 if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
183 break;
184 }
185#endif
186 }
187 sil_dly_nse(100);
188 cs_set(PORT_HIGH);
189 if(hlcd->spi_lock != 0)
190 sig_sem(hlcd->spi_lock);
191 return ercd;
192}
193
194/*
195 * LCDへのRGBデータ送信関数
196 */
197ER
198lcd_writedata3(LCD_Handler_t *hlcd, uint8_t *pbmp, uint16_t width, uint16_t height)
199{
200 ER ercd = E_OK;
201 int index, i;
202
203 if(width == 0 || height == 0)
204 return ercd;
205 if(hlcd->spi_lock != 0){
206 if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
207 return ercd;
208 }
209 dc_set(PORT_HIGH);
210 cs_set(PORT_LOW);
211 sil_dly_nse(100);
212 for(index=0; index < height; index++){
213 uint8_t *p = pbmp;
214 for (i = 0; i < width; i++){
215 aTxBuffer[0] = (*p++) & 0xf8;
216 aTxBuffer[0] |= *p >> 5;
217 aTxBuffer[1] = (*p++ << 3) & 0xE0;
218 aTxBuffer[1] |= (*p++ >> 3) & 0x1F;
219 if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
220 break;
221 }
222#if SPI_WAIT_TIME == 0
223 if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
224 break;
225 }
226#endif
227 }
228 pbmp -= width*3;
229 }
230 sil_dly_nse(100);
231 cs_set(PORT_HIGH);
232 if(hlcd->spi_lock != 0)
233 sig_sem(hlcd->spi_lock);
234 return ercd;
235}
236
237
238/*
239 * 表示ウィンドウ設定
240 */
241void
242lcd_setAddrWindow(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
243{
244 uint16_t tmp;
245
246 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_CASET)); // Column addr set
247 tmp = x0 + hlcd->colstart;
248 SVC_PERROR(lcd_writedata(hlcd, (tmp >> 8)));
249 SVC_PERROR(lcd_writedata(hlcd, (tmp & 0xFF))); // XSTART
250 tmp = x1 + hlcd->colstart;
251 SVC_PERROR(lcd_writedata(hlcd, (tmp >> 8)));
252 SVC_PERROR(lcd_writedata(hlcd, (tmp & 0xFF))); // XEND
253
254 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_PASET)); // Row addr set
255 tmp = y0 + hlcd->rowstart;
256 SVC_PERROR(lcd_writedata(hlcd, (tmp >> 8)));
257 SVC_PERROR(lcd_writedata(hlcd, (tmp & 0xFF))); // YSTART
258 tmp = y1 + hlcd->rowstart;
259 SVC_PERROR(lcd_writedata(hlcd, (tmp >> 8)));
260 SVC_PERROR(lcd_writedata(hlcd, (tmp & 0xFF))); // YEND
261
262 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_RAMWR)); // write to RAM
263}
264
265
266/*
267 * ILI9341 screensの初期化関数
268 */
269void
270lcd_init(LCD_Handler_t *hlcd, uint8_t rotation)
271{
272 hlcd->colstart = hlcd->rowstart = 0; // May be overridden in init func
273 hlcd->_width = ILI9341_TFTWIDTH;
274 hlcd->_height = ILI9341_TFTHEIGHT;
275
276 // toggle RST low to reset; CS low so it'll listen to us
277 cs_set(PORT_LOW);
278 if(hlcd->rst_pin < 14){
279 rst_set(PORT_HIGH);
280 dly_tsk(5);
281 rst_set(PORT_LOW);
282 dly_tsk(20);
283 rst_set(PORT_HIGH);
284 dly_tsk(150);
285 }
286
287 SVC_PERROR(lcd_writecommand(hlcd, 0xEF));
288 SVC_PERROR(lcd_writedata(hlcd, 0x03));
289 SVC_PERROR(lcd_writedata(hlcd, 0x80));
290 SVC_PERROR(lcd_writedata(hlcd, 0x02));
291
292 SVC_PERROR(lcd_writecommand(hlcd, 0xCF));
293 SVC_PERROR(lcd_writedata(hlcd, 0x00));
294 SVC_PERROR(lcd_writedata(hlcd, 0xC1));
295 SVC_PERROR(lcd_writedata(hlcd, 0x30));
296
297 SVC_PERROR(lcd_writecommand(hlcd, 0xED));
298 SVC_PERROR(lcd_writedata(hlcd, 0x64));
299 SVC_PERROR(lcd_writedata(hlcd, 0x03));
300 SVC_PERROR(lcd_writedata(hlcd, 0x12));
301 SVC_PERROR(lcd_writedata(hlcd, 0x81));
302
303 SVC_PERROR(lcd_writecommand(hlcd, 0xE8));
304 SVC_PERROR(lcd_writedata(hlcd, 0x85));
305 SVC_PERROR(lcd_writedata(hlcd, 0x00));
306 SVC_PERROR(lcd_writedata(hlcd, 0x78));
307
308 SVC_PERROR(lcd_writecommand(hlcd, 0xCB));
309 SVC_PERROR(lcd_writedata(hlcd, 0x39));
310 SVC_PERROR(lcd_writedata(hlcd, 0x2C));
311 SVC_PERROR(lcd_writedata(hlcd, 0x00));
312 SVC_PERROR(lcd_writedata(hlcd, 0x34));
313 SVC_PERROR(lcd_writedata(hlcd, 0x02));
314
315 SVC_PERROR(lcd_writecommand(hlcd, 0xF7));
316 SVC_PERROR(lcd_writedata(hlcd, 0x20));
317
318 SVC_PERROR(lcd_writecommand(hlcd, 0xEA));
319 SVC_PERROR(lcd_writedata(hlcd, 0x00));
320 SVC_PERROR(lcd_writedata(hlcd, 0x00));
321
322 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_PWCTR1)); /* Power control */
323 SVC_PERROR(lcd_writedata(hlcd, 0x23)); /* VRH[5:0] */
324
325 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_PWCTR2)); /* Power control */
326 SVC_PERROR(lcd_writedata(hlcd, 0x10)); /* SAP[2:0];BT[3:0] */
327
328 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_VMCTR1)); /* VCM control */
329 SVC_PERROR(lcd_writedata(hlcd, 0x3e));
330 SVC_PERROR(lcd_writedata(hlcd, 0x28));
331
332 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_VMCTR2)); /* VCM control2 */
333 SVC_PERROR(lcd_writedata(hlcd, 0x86)); /* -- */
334
335 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_MADCTL)); /* Memory Access Control */
336 SVC_PERROR(lcd_writedata(hlcd, 0x48));
337
338 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_PIXFMT));
339 SVC_PERROR(lcd_writedata(hlcd, 0x55));
340
341 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_FRMCTR1));
342 SVC_PERROR(lcd_writedata(hlcd, 0x00));
343 SVC_PERROR(lcd_writedata(hlcd, 0x18));
344
345 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_DFUNCTR)); /* Display Function Control */
346 SVC_PERROR(lcd_writedata(hlcd, 0x08));
347 SVC_PERROR(lcd_writedata(hlcd, 0x82));
348 SVC_PERROR(lcd_writedata(hlcd, 0x27));
349
350 SVC_PERROR(lcd_writecommand(hlcd, 0xF2)); /* 3Gamma Function Disable */
351 SVC_PERROR(lcd_writedata(hlcd, 0x00));
352
353 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_GAMMASET)); /* Gamma curve selected */
354 SVC_PERROR(lcd_writedata(hlcd, 0x01));
355
356 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_GMCTRP1)); /* Set Gamma */
357 SVC_PERROR(lcd_writedata(hlcd, 0x0F));
358 SVC_PERROR(lcd_writedata(hlcd, 0x31));
359 SVC_PERROR(lcd_writedata(hlcd, 0x2B));
360 SVC_PERROR(lcd_writedata(hlcd, 0x0C));
361 SVC_PERROR(lcd_writedata(hlcd, 0x0E));
362 SVC_PERROR(lcd_writedata(hlcd, 0x08));
363 SVC_PERROR(lcd_writedata(hlcd, 0x4E));
364 SVC_PERROR(lcd_writedata(hlcd, 0xF1));
365 SVC_PERROR(lcd_writedata(hlcd, 0x37));
366 SVC_PERROR(lcd_writedata(hlcd, 0x07));
367 SVC_PERROR(lcd_writedata(hlcd, 0x10));
368 SVC_PERROR(lcd_writedata(hlcd, 0x03));
369 SVC_PERROR(lcd_writedata(hlcd, 0x0E));
370 SVC_PERROR(lcd_writedata(hlcd, 0x09));
371 SVC_PERROR(lcd_writedata(hlcd, 0x00));
372
373 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_GMCTRN1)); /* Set Gamma */
374 SVC_PERROR(lcd_writedata(hlcd, 0x00));
375 SVC_PERROR(lcd_writedata(hlcd, 0x0E));
376 SVC_PERROR(lcd_writedata(hlcd, 0x14));
377 SVC_PERROR(lcd_writedata(hlcd, 0x03));
378 SVC_PERROR(lcd_writedata(hlcd, 0x11));
379 SVC_PERROR(lcd_writedata(hlcd, 0x07));
380 SVC_PERROR(lcd_writedata(hlcd, 0x31));
381 SVC_PERROR(lcd_writedata(hlcd, 0xC1));
382 SVC_PERROR(lcd_writedata(hlcd, 0x48));
383 SVC_PERROR(lcd_writedata(hlcd, 0x08));
384 SVC_PERROR(lcd_writedata(hlcd, 0x0F));
385 SVC_PERROR(lcd_writedata(hlcd, 0x0C));
386 SVC_PERROR(lcd_writedata(hlcd, 0x31));
387 SVC_PERROR(lcd_writedata(hlcd, 0x36));
388 SVC_PERROR(lcd_writedata(hlcd, 0x0F));
389
390 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_SLPOUT)); /* Exit Sleep */
391 dly_tsk(120);
392 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_DISPON)); /* Display on */
393 lcd_setRotation(hlcd, rotation);
394}
395
396/*
397 * RECTANGLEのフィル描画
398 * param1 hlcd: Pointer to LCD Handler
399 * param2 x: start X position
400 * param3 y: start Y position
401 * param4 w: width
402 * param5 h: height
403 * param6 color: color value
404 */
405void
406lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color)
407{
408 // rudimentary clipping (drawChar w/big text requires this)
409 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
410 if((x + w - 1) >= hlcd->_width) w = hlcd->_width - x;
411 if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
412
413 lcd_setAddrWindow(hlcd, x, y, x+w-1, y+h-1);
414 SVC_PERROR(lcd_writedata2(hlcd, color, h*w));
415}
416
417void
418lcd_pushColor(LCD_Handler_t *hlcd, color_t color)
419{
420 SVC_PERROR(lcd_writedata2(hlcd, color, 1));
421}
422
423/*
424 * PIXEL描画
425 * param1 hlcd: Pointer to LCD Handler
426 * param2 x: X position
427 * param3 y: Y position
428 * param4 color: color value
429 */
430void
431lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color)
432{
433 if((x < 0) ||(x >= hlcd->_width) || (y < 0) || (y >= hlcd->_height)) return;
434
435 lcd_setAddrWindow(hlcd, x, y, x, y);
436 SVC_PERROR(lcd_writedata2(hlcd, color, 1));
437}
438
439/*
440 * 垂直方向LINEの高速描画
441 * param1 hlcd: Pointer to LCD Handler
442 * param2 x: start X position
443 * param3 y: start Y position
444 * param4 h: height
445 * param5 color: color value
446 */
447void
448lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color)
449{
450 // Rudimentary clipping
451 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
452 if((y+h-1) >= hlcd->_height) h = hlcd->_height-y;
453 lcd_setAddrWindow(hlcd, x, y, x, y+h-1);
454 SVC_PERROR(lcd_writedata2(hlcd, color, h));
455}
456
457/*
458 * 水平方向LINEの高速描画
459 * param1 hlcd: Pointer to LCD Handler
460 * param2 x: start X position
461 * param3 y: start Y position
462 * param4 w: width
463 * param5 color: color value
464 */
465void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color)
466{
467 // Rudimentary clipping
468 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
469 if((x+w-1) >= hlcd->_width) w = hlcd->_width-x;
470 lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
471 SVC_PERROR(lcd_writedata2(hlcd, color, w));
472}
473
474/*
475 * DRAW IMAGE LINE描画
476 * param1 hlcd: Pointer to LCD Handler
477 * param2 x: X position
478 * param3 y: Y position
479 * param4 w: width
480 * param5 pcolor: color value
481 */
482void
483lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor)
484{
485 uint32_t i;
486
487 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
488 if((x+w-1) >= hlcd->_width) w = hlcd->_width-x;
489
490 lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
491 for(i = 0 ; i < w ; i++, pcolor++)
492 SVC_PERROR(lcd_writedata2(hlcd, *pcolor, 1));
493}
494
495/*
496 * BITMAP描画
497 * param1 hlcd: Pointer to LCD Handler
498 * param2 x0: Bmp X position in the LCD
499 * param3 y0: Bmp Y position in the LCD
500 * param4 pbmp: Pointer to Bmp picture address in the internal Flash
501 */
502void
503lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp)
504{
505 uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
506 uint32_t input_color_mode = 0;
507
508 /* Get bitmap data address offset */
509 index = *(uint16_t *) (pbmp + 10);
510 index |= (*(uint16_t *) (pbmp + 12)) << 16;
511
512 /* Read bitmap width */
513 width = *(uint16_t *) (pbmp + 18);
514 width |= (*(uint16_t *) (pbmp + 20)) << 16;
515
516 /* Read bitmap height */
517 height = *(uint16_t *) (pbmp + 22);
518 height |= (*(uint16_t *) (pbmp + 24)) << 16;
519
520 /* Read bit/pixel */
521 bit_pixel = *(uint16_t *) (pbmp + 28);
522
523 /* Get the layer pixel format */
524 if ((bit_pixel/8) == 4){
525 input_color_mode = CM_ARGB8888;
526 }
527 else if ((bit_pixel/8) == 2){
528 input_color_mode = CM_RGB565;
529 }
530 else{
531 input_color_mode = CM_RGB888;
532 }
533
534 /* Bypass the bitmap header */
535 pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
536 syslog_4(LOG_INFO, "lcd_drawBitmap input_color_mode(%d) width(%d) height(%d) bit_pixel(%d)", input_color_mode, width, height, bit_pixel);
537
538 lcd_setAddrWindow(hlcd, x0, y0, x0+width-1, y0+height-1);
539 lcd_writedata3(hlcd, pbmp, width, height);
540}
541
542/*
543 * ROTATION設定
544 * param1 hlcd: Pointer to LCD Handler
545 * param2 m: 0:0, 1:90, 2:180, 3:270
546 */
547void
548lcd_setRotation(LCD_Handler_t *hlcd, uint8_t m)
549{
550 SVC_PERROR(lcd_writecommand(hlcd, ILI9341_MADCTL));
551 hlcd->rotation = m % 4; // can't be higher than 3
552 switch(hlcd->rotation){
553 case 1:
554 SVC_PERROR(lcd_writedata(hlcd, (MADCTL_MV | MADCTL_BGR)));
555 hlcd->_width = ILI9341_TFTHEIGHT;
556 hlcd->_height = ILI9341_TFTWIDTH;
557 break;
558 case 2:
559 SVC_PERROR(lcd_writedata(hlcd, (MADCTL_MY | MADCTL_BGR)));
560 hlcd->_width = ILI9341_TFTWIDTH;
561 hlcd->_height = ILI9341_TFTHEIGHT;
562 break;
563 case 3:
564 SVC_PERROR(lcd_writedata(hlcd, (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR)));
565 hlcd->_width = ILI9341_TFTHEIGHT;
566 hlcd->_height = ILI9341_TFTWIDTH;
567 break;
568 case 0:
569 default:
570 SVC_PERROR(lcd_writedata(hlcd, (MADCTL_MX | MADCTL_BGR)));
571 hlcd->_width = ILI9341_TFTWIDTH;
572 hlcd->_height = ILI9341_TFTHEIGHT;
573 break;
574 }
575}
576
577/*
578 * INVERT DISPLAY
579 * param1 hlcd: Pointer to LCD Handler
580 * param2 i: invert value
581 */
582void
583lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i)
584{
585 SVC_PERROR(lcd_writecommand(hlcd, i ? ILI9341_INVON : ILI9341_INVOFF));
586}
587
588
589/*
590 * スクリーンフィル
591 * param1 pDrawProp: Pointer to Draw Prop
592 */
593void
594lcd_fillScreen(LCD_DrawProp_t *pDrawProp)
595{
596 lcd_fillRect(pDrawProp->hlcd, 0, 0, pDrawProp->hlcd->_width, pDrawProp->hlcd->_height, pDrawProp->BackColor);
597}
598
599/*
600 * RECTANGLE描画
601 * param1 pDrawProp: Pointer to Draw Prop
602 * param2 x: left X position
603 * param3 y: top Y position
604 * param4 w: width
605 * param5 h: height
606 */
607void
608lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h)
609{
610 LCD_Handler_t *hlcd = pDrawProp->hlcd;
611 color_t color;
612
613 // rudimentary clipping (drawChar w/big text requires this)
614 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
615 if((x + w - 1) >= hlcd->_width) w = hlcd->_width - x;
616 if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
617
618 color = pDrawProp->TextColor;
619 lcd_drawFastVLine(hlcd, x, y, h, color);
620 lcd_drawFastHLine(hlcd, x, y+h-1, w, color);
621 lcd_drawFastVLine(hlcd, x+w-1, y, h, color);
622 lcd_drawFastHLine(hlcd, x, y, w, color);
623}
624
625/*
626 * 円描画
627 * param1 pDrawProp: Pointer to Draw Prop
628 * param2 x0: X position
629 * param3 y0: Y position
630 * param4 Radius: Circle radius
631 */
632void
633lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius)
634{
635 LCD_Handler_t *hlcd = pDrawProp->hlcd;
636 int32_t decision; /* Decision Variable */
637 uint32_t current_x; /* Current X Value */
638 uint32_t current_y; /* Current Y Value */
639
640 decision = 3 - (Radius << 1);
641 current_x = 0;
642 current_y = Radius;
643
644 while(current_x <= current_y){
645 lcd_drawPixel(hlcd, (x0 + current_x), (y0 - current_y), pDrawProp->TextColor);
646 lcd_drawPixel(hlcd, (x0 - current_x), (y0 - current_y), pDrawProp->TextColor);
647 lcd_drawPixel(hlcd, (x0 + current_y), (y0 - current_x), pDrawProp->TextColor);
648 lcd_drawPixel(hlcd, (x0 - current_y), (y0 - current_x), pDrawProp->TextColor);
649 lcd_drawPixel(hlcd, (x0 + current_x), (y0 + current_y), pDrawProp->TextColor);
650 lcd_drawPixel(hlcd, (x0 - current_x), (y0 + current_y), pDrawProp->TextColor);
651 lcd_drawPixel(hlcd, (x0 + current_y), (y0 + current_x), pDrawProp->TextColor);
652 lcd_drawPixel(hlcd, (x0 - current_y), (y0 + current_x), pDrawProp->TextColor);
653
654 if (decision < 0){
655 decision += (current_x << 2) + 6;
656 }
657 else{
658 decision += ((current_x - current_y) << 2) + 10;
659 current_y--;
660 }
661 current_x++;
662 }
663}
664
665/*
666 * 線描画
667 * param1 pDrawProp: Pointer to Draw Prop
668 * param2 x1: Point 1 X position
669 * param3 y1: Point 1 Y position
670 * param4 x2: Point 2 X position
671 * param5 y2: Point 2 Y position
672 */
673void
674lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
675{
676 LCD_Handler_t *hlcd = pDrawProp->hlcd;
677 int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
678 yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0,
679 curpixel = 0;
680
681 deltax = ABS(x2 - x1); /* The difference between the x's */
682 deltay = ABS(y2 - y1); /* The difference between the y's */
683 x = x1; /* Start x off at the first pixel */
684 y = y1; /* Start y off at the first pixel */
685
686 if(x2 >= x1){ /* The x-values are increasing */
687 xinc1 = 1;
688 xinc2 = 1;
689 }
690 else{ /* The x-values are decreasing */
691 xinc1 = -1;
692 xinc2 = -1;
693 }
694
695 if(y2 >= y1){ /* The y-values are increasing */
696 yinc1 = 1;
697 yinc2 = 1;
698 }
699 else{ /* The y-values are decreasing */
700 yinc1 = -1;
701 yinc2 = -1;
702 }
703
704 if(deltax >= deltay){ /* There is at least one x-value for every y-value */
705 xinc1 = 0; /* Don't change the x when numerator >= denominator */
706 yinc2 = 0; /* Don't change the y for every iteration */
707 den = deltax;
708 num = deltax / 2;
709 num_add = deltay;
710 num_pixels = deltax; /* There are more x-values than y-values */
711 }
712 else{ /* There is at least one y-value for every x-value */
713 xinc2 = 0; /* Don't change the x for every iteration */
714 yinc1 = 0; /* Don't change the y when numerator >= denominator */
715 den = deltay;
716 num = deltay / 2;
717 num_add = deltax;
718 num_pixels = deltay; /* There are more y-values than x-values */
719 }
720
721 for (curpixel = 0; curpixel <= num_pixels; curpixel++){
722 lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor); /* Draw the current pixel */
723 num += num_add; /* Increase the numerator by the top of the fraction */
724 if(num >= den){ /* Check if numerator >= denominator */
725 num -= den; /* Calculate the new numerator value */
726 x += xinc1; /* Change the x as appropriate */
727 y += yinc1; /* Change the y as appropriate */
728 }
729 x += xinc2; /* Change the x as appropriate */
730 y += yinc2; /* Change the y as appropriate */
731 }
732}
733
734/*
735 * PLOY-LINE描画
736 * param1 pDrawProp: Pointer to Draw Prop
737 * param2 Points: Pointer to the points array
738 * param3 PointCount: Number of points
739 */
740void
741lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
742{
743 int16_t x = 0, y = 0;
744
745 if(PointCount < 2){
746 return;
747 }
748
749 lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
750 while(--PointCount){
751 x = Points->X;
752 y = Points->Y;
753 Points++;
754 lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
755 }
756}
757
Note: See TracBrowser for help on using the repository browser.