source: azure_iot_hub_riscv/trunk/asp_baseplatform/gdic/adafruit_st7789/adafruit_st7789.c@ 453

Last change on this file since 453 was 453, 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.8 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 * Copyright (C) 2015-2020 by TOPPERS PROJECT Educational Working Group.
11 *
12 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * と.
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * 報告すること.
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
32 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
33 * 免責すること.
34 *
35 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
36 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
37 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
38 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
39 * の責任を負わない.
40 *
41 * $Id$
42 */
43
44/*
45 * Written by Limor Fried/Ladyada for Adafruit Industries.
46 * MIT license, all text above must be included in any redistribution
47 * http://opensource.org/licenses/mit-license.php
48 */
49
50/*
51 * ADAFRUIT ST7789 LCD制御プログラムの本体
52 */
53
54#include <kernel.h>
55#include <t_syslog.h>
56#include <t_stdlib.h>
57#include <stdio.h>
58#include <string.h>
59#include <target_syssvc.h>
60#include "syssvc/serial.h"
61#include "syssvc/syslog.h"
62#include "device.h"
63#include "adafruit_st7789.h"
64
65/*
66 * サービスコールのエラーのログ出力
67 */
68Inline void
69svc_perror(const char *file, int_t line, const char *expr, ER ercd)
70{
71 if (ercd < 0) {
72 t_perror(LOG_ERROR, file, line, expr, ercd);
73 }
74}
75
76#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
77#define ABS(X) ((X) > 0 ? (X) : -(X))
78
79
80// Rather than a bazillion writecommand() and writedata() calls, screen
81// initialization commands and arguments are organized in these tables
82// stored in PROGMEM. The table may look bulky, but that's mostly the
83// formatting -- storage-wise this is hundreds of bytes more compact
84// than the equivalent code. Companion function follows.
85#define DELAY 0x80
86static const uint8_t
87 Gcmd[] = { // Initialization commands for 7789 screens
88 9, // 9 commands in list:
89 ST7789_SWRESET, DELAY, // 1: Software reset, no args, w/delay
90 150, // 150 ms delay
91 ST7789_SLPOUT , DELAY, // 2: Out of sleep mode, no args, w/delay
92 10, // 10 ms delay
93 ST7789_COLMOD , 1+DELAY, // 3: Set color mode, 1 arg + delay:
94 0x55, // 16-bit color
95 10, // 10 ms delay
96 ST7789_MADCTL , 1, // 4: Mem access ctrl (directions), 1 arg:
97 0x08, // Row/col addr, bottom-top refresh
98 ST7789_CASET , 4, // 5: Column addr set, 4 args, no delay:
99 0x00, //
100 0, // XSTART = 0
101 0, //
102 240, // XEND = 240
103 ST7789_RASET , 4, // 6: Row addr set, 4 args, no delay:
104 0x00,
105 0, // YSTART = 0
106 320>>8,
107 320&0xFF, // YEND = 320
108 ST7789_INVON , DELAY, // 7: hack
109 10, // 10 ms delay
110 ST7789_NORON , DELAY, // 8: Normal display on, no args, w/delay
111 10, // 10 ms delay
112 ST7789_DISPON , DELAY, // 9: Main screen turn on, no args, delay
113 10 }; // 10 ms delay
114
115
116
117
118/* Buffer used for transmission */
119static uint8_t aTxBuffer[4];
120
121#define PORT_HIGH 1
122#define PORT_LOW 0
123
124#define cs_set(sw) digitalWrite(hlcd->cs_pin, sw)
125#define rs_set(sw) digitalWrite(hlcd->rs_pin, sw)
126#define rst_set(sw) digitalWrite(hlcd->rst_pin, sw)
127#define cs2_set(sw) digitalWrite(hlcd->cs2_pin, sw)
128
129/*
130 * LCDへのコマンド送信関数
131 */
132ER
133lcd_writecommand(LCD_Handler_t *hlcd, uint8_t c)
134{
135 ER ercd = E_OK;
136
137 if(hlcd->spi_lock != 0){
138 if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
139 return ercd;
140 }
141 rs_set(PORT_LOW);
142 cs_set(PORT_LOW);
143
144 aTxBuffer[0] = c;
145#if SPI_WAIT_TIME != 0
146 ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1);
147#else
148 if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 1)) == E_OK){
149 ercd = spi_wait(hlcd->hspi, 100);
150 }
151#endif
152
153 cs_set(PORT_HIGH);
154 if(hlcd->spi_lock != 0)
155 sig_sem(hlcd->spi_lock);
156 return ercd;
157}
158
159/*
160 * LCDへのデータ送信関数
161 */
162ER
163lcd_writedata(LCD_Handler_t *hlcd, uint8_t *p, uint32_t len)
164{
165 ER ercd = E_OK;
166
167 if(hlcd->spi_lock != 0){
168 if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
169 return ercd;
170 }
171 rs_set(PORT_HIGH);
172 cs_set(PORT_LOW);
173 sil_dly_nse(100);
174
175#if SPI_WAIT_TIME != 0
176 ercd = spi_transmit(hlcd->hspi, (uint8_t*)p, len);
177#else
178 if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)p, len)) == E_OK){
179 ercd = spi_wait(hlcd->hspi, 100);
180 }
181#endif
182
183 sil_dly_nse(100);
184 cs_set(PORT_HIGH);
185 if(hlcd->spi_lock != 0)
186 sig_sem(hlcd->spi_lock);
187 return ercd;
188}
189
190/*
191 * LCDへの2バイトデータ送信関数
192 */
193ER
194lcd_writedata2(LCD_Handler_t *hlcd, uint16_t c, int cnt)
195{
196 ER ercd = E_OK;
197 int i;
198
199 if(cnt == 0)
200 return ercd;
201 if(hlcd->spi_lock != 0){
202 if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
203 return ercd;
204 }
205 rs_set(PORT_HIGH);
206 cs_set(PORT_LOW);
207 sil_dly_nse(100);
208 aTxBuffer[0] = c>>8;
209 aTxBuffer[1] = (uint8_t)c;
210 for(i = 0 ; i < cnt ; i++){
211 if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
212 break;
213 }
214#if SPI_WAIT_TIME == 0
215 if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
216 break;
217 }
218#endif
219 }
220 sil_dly_nse(100);
221 cs_set(PORT_HIGH);
222 if(hlcd->spi_lock != 0)
223 sig_sem(hlcd->spi_lock);
224 return ercd;
225}
226
227/*
228 * LCDへのRGBデータ送信関数
229 */
230ER
231lcd_writedata3(LCD_Handler_t *hlcd, uint8_t *pbmp, uint16_t width, uint16_t height)
232{
233 ER ercd = E_OK;
234 int index, i;
235
236 if(width == 0 || height == 0)
237 return ercd;
238 if(hlcd->spi_lock != 0){
239 if((ercd = wai_sem(hlcd->spi_lock)) != E_OK)
240 return ercd;
241 }
242 rs_set(PORT_HIGH);
243 cs_set(PORT_LOW);
244 sil_dly_nse(100);
245 for(index=0; index < height; index++){
246 uint8_t *p = pbmp;
247 for (i = 0; i < width; i++){
248 aTxBuffer[0] = (*p++) & 0xf8;
249 aTxBuffer[0] |= *p >> 5;
250 aTxBuffer[1] = (*p++ << 3) & 0xE0;
251 aTxBuffer[1] |= (*p++ >> 3) & 0x1F;
252 if((ercd = spi_transmit(hlcd->hspi, (uint8_t*)aTxBuffer, 2)) != E_OK){
253 break;
254 }
255#if SPI_WAIT_TIME == 0
256 if((ercd = spi_wait(hlcd->hspi, 100)) != E_OK){
257 break;
258 }
259#endif
260 }
261 pbmp -= width*3;
262 }
263 sil_dly_nse(100);
264 cs_set(PORT_HIGH);
265 if(hlcd->spi_lock != 0)
266 sig_sem(hlcd->spi_lock);
267 return ercd;
268}
269
270/*
271 * ST7789へのコマンドリスト送信
272 */
273static void
274displayInit(LCD_Handler_t *hlcd, const uint8_t *addr)
275{
276 uint8_t numCommands, numArgs;
277 uint8_t data[4];
278 uint16_t ms;
279
280 numCommands = *addr++; // Number of commands to follow
281 while(numCommands--) { // For each command...
282 SVC_PERROR(lcd_writecommand(hlcd, *addr++)); // Read, issue command
283 numArgs = *addr++; // Number of args to follow
284 ms = numArgs & DELAY; // If hibit set, delay follows args
285 numArgs &= ~DELAY; // Mask out delay bit
286 while(numArgs--) { // For each argument...
287 data[0] = *addr++;
288 SVC_PERROR(lcd_writedata(hlcd, data, 1)); // Read, issue argument
289 }
290
291 if(ms) {
292 ms = *addr++; // Read post-command delay time (ms)
293 if(ms == 255) ms = 500; // If 255, delay for 500 ms
294 dly_tsk(ms);
295 }
296 }
297}
298
299
300/*
301 * ST7735B または ST7735RタイプのLEDの共通初期化関数
302 */
303static void
304commonInit(LCD_Handler_t *hlcd, uint16_t width, uint16_t height)
305{
306 hlcd->colstart = hlcd->rowstart = 0; // May be overridden in init func
307 hlcd->lcd_width = width;
308 hlcd->lcd_height = height;
309 if(width == 240 && height == 240){ /* 1.3" and 1.54 displays */
310 hlcd->lcd_colstart = 0;
311 hlcd->lcd_rowstart = 80;
312 }
313 else if(width == 135 && height == 240){ /*1.13" display */
314 hlcd->lcd_colstart = 53;
315 hlcd->lcd_rowstart = 40;
316 }
317 else{
318 hlcd->lcd_colstart = 0;
319 hlcd->lcd_rowstart = 0;
320 }
321
322 // toggle RST low to reset; CS low so it'll listen to us
323 cs_set(PORT_LOW);
324 rst_set(PORT_HIGH);
325 dly_tsk(500);
326 rst_set(PORT_LOW);
327 dly_tsk(500);
328 rst_set(PORT_HIGH);
329}
330
331/*
332 * 表示ウィンドウ設定
333 */
334void
335lcd_setAddrWindow(LCD_Handler_t *hlcd, uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
336{
337 uint8_t data[4];
338
339 SVC_PERROR(lcd_writecommand(hlcd, ST7789_CASET)); // Column addr set
340 data[0] = (uint8_t)((x0 + hlcd->colstart) >> 8);
341 data[1] = (uint8_t)(x0 + hlcd->colstart); // XSTART
342 data[2] = (uint8_t)((x1 + hlcd->colstart) >> 8);
343 data[3] = (uint8_t)(x1 + hlcd->colstart); // XEND
344 SVC_PERROR(lcd_writedata(hlcd, data, 4));
345
346 SVC_PERROR(lcd_writecommand(hlcd, ST7789_RASET)); // Row addr set
347 data[0] = (uint8_t)((y0 + hlcd->rowstart) >> 8);
348 data[1] = (uint8_t)(y0 + hlcd->rowstart); // YSTART
349 data[2] = (uint8_t)((y1 + hlcd->rowstart) >> 8);
350 data[3] = (uint8_t)(y1 + hlcd->rowstart); // YEND
351 SVC_PERROR(lcd_writedata(hlcd, data, 4));
352
353 SVC_PERROR(lcd_writecommand(hlcd, ST7789_RAMWR)); // write to RAM
354}
355
356/*
357 * オリエンテーション設定
358 * param1 hlcd: Pointer to LCD Handler
359 * param2 m: orientation value(0-3)
360 */
361void
362lcd_setRotation(LCD_Handler_t *hlcd, uint8_t m)
363{
364 uint8_t madctl[4];
365
366 hlcd->rotation = m & 3; // can't be higher than 3
367 madctl[0] = 0;
368
369 switch(hlcd->rotation){
370 case 0:
371 madctl[0] = ST7789_MADCTL_MX | ST7789_MADCTL_MY | ST7789_MADCTL_RGB;
372 hlcd->colstart = hlcd->lcd_colstart;
373 hlcd->rowstart = hlcd->lcd_rowstart;
374 hlcd->_width = hlcd->lcd_width;
375 hlcd->_height = hlcd->lcd_height;
376 break;
377 case 1:
378 madctl[0] = ST7789_MADCTL_MY | ST7789_MADCTL_MV | ST7789_MADCTL_RGB;
379 hlcd->colstart = hlcd->lcd_rowstart;
380 hlcd->rowstart = hlcd->lcd_colstart;
381 hlcd->_height = hlcd->lcd_width;
382 hlcd->_width = hlcd->lcd_height;
383 break;
384 case 2:
385 madctl[0] = ST7789_MADCTL_RGB;
386 if(hlcd->lcd_width == 135 && hlcd->lcd_height == 240){
387 hlcd->colstart = hlcd->lcd_colstart-1;
388 hlcd->rowstart = hlcd->lcd_rowstart;
389 }
390 else{
391 hlcd->colstart = 0;
392 hlcd->rowstart = 0;
393 }
394 hlcd->_width = hlcd->lcd_width;
395 hlcd->_height = hlcd->lcd_height;
396 break;
397 case 3:
398 madctl[0] = ST7789_MADCTL_MX | ST7789_MADCTL_MV | ST7789_MADCTL_RGB;
399 if(hlcd->lcd_width == 135 && hlcd->lcd_height == 240){
400 hlcd->colstart = hlcd->lcd_rowstart;
401 hlcd->rowstart = hlcd->lcd_colstart;
402 }
403 else{
404 hlcd->colstart = 0;
405 hlcd->rowstart = 0;
406 }
407 hlcd->_height = hlcd->lcd_width;
408 hlcd->_width = hlcd->lcd_height;
409 break;
410 }
411 SVC_PERROR(lcd_writecommand(hlcd, ST7789_MADCTL));
412 SVC_PERROR(lcd_writedata(hlcd, madctl, 1));
413}
414
415/*
416 * ST7789 screensの初期化関数
417 */
418void
419lcd_init(LCD_Handler_t *hlcd, uint16_t width, uint16_t height)
420{
421 commonInit(hlcd, width, height);
422
423 displayInit(hlcd, Gcmd);
424 lcd_setRotation(hlcd, hlcd->rotation);
425 syslog_2(LOG_NOTICE, "## width(%d) height(%d) ##", hlcd->_width, hlcd->_height);
426}
427
428/*
429 * RECTANGLEのフィル描画
430 * param1 hlcd: Pointer to LCD Handler
431 * param2 x: start X position
432 * param3 y: start Y position
433 * param4 w: width
434 * param5 h: height
435 * param6 color: color value
436 */
437void
438lcd_fillRect(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, int16_t h, color_t color)
439{
440 // rudimentary clipping (drawChar w/big text requires this)
441 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
442 if((x + w - 1) >= hlcd->_width) w = hlcd->_width - x;
443 if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
444
445 lcd_setAddrWindow(hlcd, x, y, x+w-1, y+h-1);
446 SVC_PERROR(lcd_writedata2(hlcd, color, h*w));
447}
448
449void
450lcd_pushColor(LCD_Handler_t *hlcd, color_t color)
451{
452 SVC_PERROR(lcd_writedata2(hlcd, color, 1));
453}
454
455/*
456 * PIXEL描画
457 * param1 hlcd: Pointer to LCD Handler
458 * param2 x: X position
459 * param3 y: Y position
460 * param4 color: color value
461 */
462void
463lcd_drawPixel(LCD_Handler_t *hlcd, int16_t x, int16_t y, color_t color)
464{
465 if((x < 0) ||(x >= hlcd->_width) || (y < 0) || (y >= hlcd->_height)) return;
466
467 lcd_setAddrWindow(hlcd, x, y, x, y);
468 SVC_PERROR(lcd_writedata2(hlcd, color, 1));
469}
470
471/*
472 * 垂直方向LINEの高速描画
473 * param1 hlcd: Pointer to LCD Handler
474 * param2 x: start X position
475 * param3 y: start Y position
476 * param4 h: height
477 * param5 color: color value
478 */
479void
480lcd_drawFastVLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t h, color_t color)
481{
482 // Rudimentary clipping
483 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
484 if((y+h-1) >= hlcd->_height) h = hlcd->_height-y;
485 lcd_setAddrWindow(hlcd, x, y, x, y+h-1);
486 SVC_PERROR(lcd_writedata2(hlcd, color, h));
487}
488
489/*
490 * 水平方向LINEの高速描画
491 * param1 hlcd: Pointer to LCD Handler
492 * param2 x: start X position
493 * param3 y: start Y position
494 * param4 w: width
495 * param5 color: color value
496 */
497void lcd_drawFastHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, int16_t w, color_t color)
498{
499 // Rudimentary clipping
500 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
501 if((x+w-1) >= hlcd->_width) w = hlcd->_width-x;
502 lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
503 SVC_PERROR(lcd_writedata2(hlcd, color, w));
504}
505
506/*
507 * DRAW IMAGE LINE描画
508 * param1 hlcd: Pointer to LCD Handler
509 * param2 x: X position
510 * param3 y: Y position
511 * param4 w: width
512 * param5 pcolor: color value
513 */
514void
515lcd_drawImageHLine(LCD_Handler_t *hlcd, int16_t x, int16_t y, uint16_t w, color_t *pcolor)
516{
517 uint32_t i;
518
519 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
520 if((x+w-1) >= hlcd->_width) w = hlcd->_width-x;
521
522 lcd_setAddrWindow(hlcd, x, y, x+w-1, y);
523 for(i = 0 ; i < w ; i++, pcolor++)
524 SVC_PERROR(lcd_writedata2(hlcd, *pcolor, 1));
525}
526
527/*
528 * BITMAP描画
529 * param1 hlcd: Pointer to LCD Handler
530 * param2 x0: Bmp X position in the LCD
531 * param3 y0: Bmp Y position in the LCD
532 * param4 pbmp: Pointer to Bmp picture address in the internal Flash
533 */
534void
535lcd_drawBitmap(LCD_Handler_t *hlcd, uint16_t x0, uint16_t y0, uint8_t *pbmp)
536{
537 uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
538 uint32_t input_color_mode = 0;
539
540 /* Get bitmap data address offset */
541 index = *(uint16_t *) (pbmp + 10);
542 index |= (*(uint16_t *) (pbmp + 12)) << 16;
543
544 /* Read bitmap width */
545 width = *(uint16_t *) (pbmp + 18);
546 width |= (*(uint16_t *) (pbmp + 20)) << 16;
547
548 /* Read bitmap height */
549 height = *(uint16_t *) (pbmp + 22);
550 height |= (*(uint16_t *) (pbmp + 24)) << 16;
551
552 /* Read bit/pixel */
553 bit_pixel = *(uint16_t *) (pbmp + 28);
554
555 /* Get the layer pixel format */
556 if ((bit_pixel/8) == 4){
557 input_color_mode = CM_ARGB8888;
558 }
559 else if ((bit_pixel/8) == 2){
560 input_color_mode = CM_RGB565;
561 }
562 else{
563 input_color_mode = CM_RGB888;
564 }
565
566 /* Bypass the bitmap header */
567 pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
568 syslog_4(LOG_NOTICE, "## input_color_mode(%d) width(%d) height(%d) bit_pixel(%d) ##", input_color_mode, width, height, bit_pixel);
569
570 lcd_setAddrWindow(hlcd, x0, y0, x0+width-1, y0+height-1);
571 lcd_writedata3(hlcd, pbmp, width, height);
572}
573
574/*
575 * INVERT DISPLAY
576 * param1 hlcd: Pointer to LCD Handler
577 * param2 i: invert value
578 */
579void
580lcd_invertDisplay(LCD_Handler_t *hlcd, bool_t i)
581{
582 SVC_PERROR(lcd_writecommand(hlcd, i ? ST7789_INVOFF : ST7789_INVON));
583}
584
585
586/*
587 * スクリーンフィル
588 * param1 pDrawProp: Pointer to Draw Prop
589 */
590void
591lcd_fillScreen(LCD_DrawProp_t *pDrawProp)
592{
593 lcd_fillRect(pDrawProp->hlcd, 0, 0, pDrawProp->hlcd->_width, pDrawProp->hlcd->_height, pDrawProp->BackColor);
594}
595
596/*
597 * RECTANGLE描画
598 * param1 pDrawProp: Pointer to Draw Prop
599 * param2 x: left X position
600 * param3 y: top Y position
601 * param4 w: width
602 * param5 h: height
603 */
604void
605lcd_drawRect(LCD_DrawProp_t *pDrawProp, int16_t x, int16_t y, int16_t w, int16_t h)
606{
607 LCD_Handler_t *hlcd = pDrawProp->hlcd;
608 color_t color;
609
610 // rudimentary clipping (drawChar w/big text requires this)
611 if((x >= hlcd->_width) || (y >= hlcd->_height)) return;
612 if((x + w - 1) >= hlcd->_width) w = hlcd->_width - x;
613 if((y + h - 1) >= hlcd->_height) h = hlcd->_height - y;
614
615 color = pDrawProp->TextColor;
616 lcd_drawFastVLine(hlcd, x, y, h, color);
617 lcd_drawFastHLine(hlcd, x, y+h-1, w, color);
618 lcd_drawFastVLine(hlcd, x+w-1, y, h, color);
619 lcd_drawFastHLine(hlcd, x, y, w, color);
620}
621
622/*
623 * 円描画
624 * param1 pDrawProp: Pointer to Draw Prop
625 * param2 x0: X position
626 * param3 y0: Y position
627 * param4 Radius: Circle radius
628 */
629void
630lcd_DrawCircle(LCD_DrawProp_t *pDrawProp, uint16_t x0, uint16_t y0, uint16_t Radius)
631{
632 LCD_Handler_t *hlcd = pDrawProp->hlcd;
633 int32_t decision; /* Decision Variable */
634 uint32_t current_x; /* Current X Value */
635 uint32_t current_y; /* Current Y Value */
636
637 decision = 3 - (Radius << 1);
638 current_x = 0;
639 current_y = Radius;
640
641 while(current_x <= current_y){
642 lcd_drawPixel(hlcd, (x0 + current_x), (y0 - current_y), pDrawProp->TextColor);
643 lcd_drawPixel(hlcd, (x0 - current_x), (y0 - current_y), pDrawProp->TextColor);
644 lcd_drawPixel(hlcd, (x0 + current_y), (y0 - current_x), pDrawProp->TextColor);
645 lcd_drawPixel(hlcd, (x0 - current_y), (y0 - current_x), pDrawProp->TextColor);
646 lcd_drawPixel(hlcd, (x0 + current_x), (y0 + current_y), pDrawProp->TextColor);
647 lcd_drawPixel(hlcd, (x0 - current_x), (y0 + current_y), pDrawProp->TextColor);
648 lcd_drawPixel(hlcd, (x0 + current_y), (y0 + current_x), pDrawProp->TextColor);
649 lcd_drawPixel(hlcd, (x0 - current_y), (y0 + current_x), pDrawProp->TextColor);
650
651 if (decision < 0){
652 decision += (current_x << 2) + 6;
653 }
654 else{
655 decision += ((current_x - current_y) << 2) + 10;
656 current_y--;
657 }
658 current_x++;
659 }
660}
661
662/*
663 * 線描画
664 * param1 pDrawProp: Pointer to Draw Prop
665 * param2 x1: Point 1 X position
666 * param3 y1: Point 1 Y position
667 * param4 x2: Point 2 X position
668 * param5 y2: Point 2 Y position
669 */
670void
671lcd_drawLine(LCD_DrawProp_t *pDrawProp, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
672{
673 LCD_Handler_t *hlcd = pDrawProp->hlcd;
674 int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
675 yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0,
676 curpixel = 0;
677
678 deltax = ABS(x2 - x1); /* The difference between the x's */
679 deltay = ABS(y2 - y1); /* The difference between the y's */
680 x = x1; /* Start x off at the first pixel */
681 y = y1; /* Start y off at the first pixel */
682
683 if(x2 >= x1){ /* The x-values are increasing */
684 xinc1 = 1;
685 xinc2 = 1;
686 }
687 else{ /* The x-values are decreasing */
688 xinc1 = -1;
689 xinc2 = -1;
690 }
691
692 if(y2 >= y1){ /* The y-values are increasing */
693 yinc1 = 1;
694 yinc2 = 1;
695 }
696 else{ /* The y-values are decreasing */
697 yinc1 = -1;
698 yinc2 = -1;
699 }
700
701 if(deltax >= deltay){ /* There is at least one x-value for every y-value */
702 xinc1 = 0; /* Don't change the x when numerator >= denominator */
703 yinc2 = 0; /* Don't change the y for every iteration */
704 den = deltax;
705 num = deltax / 2;
706 num_add = deltay;
707 num_pixels = deltax; /* There are more x-values than y-values */
708 }
709 else{ /* There is at least one y-value for every x-value */
710 xinc2 = 0; /* Don't change the x for every iteration */
711 yinc1 = 0; /* Don't change the y when numerator >= denominator */
712 den = deltay;
713 num = deltay / 2;
714 num_add = deltax;
715 num_pixels = deltay; /* There are more y-values than x-values */
716 }
717
718 for (curpixel = 0; curpixel <= num_pixels; curpixel++){
719 lcd_drawPixel(hlcd, x, y, pDrawProp->TextColor); /* Draw the current pixel */
720 num += num_add; /* Increase the numerator by the top of the fraction */
721 if(num >= den){ /* Check if numerator >= denominator */
722 num -= den; /* Calculate the new numerator value */
723 x += xinc1; /* Change the x as appropriate */
724 y += yinc1; /* Change the y as appropriate */
725 }
726 x += xinc2; /* Change the x as appropriate */
727 y += yinc2; /* Change the y as appropriate */
728 }
729}
730
731/*
732 * PLOY-LINE描画
733 * param1 pDrawProp: Pointer to Draw Prop
734 * param2 Points: Pointer to the points array
735 * param3 PointCount: Number of points
736 */
737void
738lcd_drawPolygon(LCD_DrawProp_t *pDrawProp, pPoint Points, uint16_t PointCount)
739{
740 int16_t x = 0, y = 0;
741
742 if(PointCount < 2){
743 return;
744 }
745
746 lcd_drawLine(pDrawProp, Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
747 while(--PointCount){
748 x = Points->X;
749 y = Points->Y;
750 Points++;
751 lcd_drawLine(pDrawProp, x, y, Points->X, Points->Y);
752 }
753}
754
Note: See TracBrowser for help on using the repository browser.