]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_SAMV71_Xplained_AtmelStudio/libboard_samv7-ek/source/lcd_draw.c
Add SAMV7 (Cortex-M7) demo for Atmel Studio.
[freertos] / FreeRTOS / Demo / CORTEX_M7_SAMV71_Xplained_AtmelStudio / libboard_samv7-ek / source / lcd_draw.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License\r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2011, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 /**\r
31  * \file\r
32  *\r
33  * Implementation of draw function on LCD, Include draw text, image\r
34  * and basic shapes (line, rectangle, circle).\r
35  *\r
36  */\r
37 \r
38 /*----------------------------------------------------------------------------\r
39  *        Headers\r
40  *----------------------------------------------------------------------------*/\r
41 \r
42 #include "board.h"\r
43 \r
44 #include <stdint.h>\r
45 #include <string.h>\r
46 #include <assert.h>\r
47 \r
48 /*----------------------------------------------------------------------------\r
49  *        Local variables\r
50  *----------------------------------------------------------------------------*/\r
51 static void* gpCanvasBuffer;\r
52 static uint32_t gwCanvasBufferSize;\r
53 static uint32_t gwCanvasMaxWidth, gwCanvasMaxHeight;\r
54 extern uint8_t ili9488_lcdMode;\r
55 /*----------------------------------------------------------------------------\r
56  *        Local functions\r
57  *----------------------------------------------------------------------------*/\r
58 \r
59 /*\r
60  * \brief Fill rectangle with given color\r
61  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
62  * \param rc  rectangle defines X and Y coordinate, width and height of windows.\r
63  * \param dwColor color to be filled.\r
64  */\r
65 static void LCDD_FillSolidRect(uint16_t *pCanvasBuffer, rect rc, uint32_t dwColor )\r
66 {\r
67         uint32_t row, col;\r
68         uint32_t w,h;\r
69         \r
70         //assert(gpCanvasBuffer!=NULL);\r
71         w = rc.x + rc.width;\r
72         w = w > gwCanvasMaxWidth ? gwCanvasMaxWidth : w;\r
73         h = rc.y + rc.height;\r
74         h = h > gwCanvasMaxHeight ? gwCanvasMaxHeight : h;\r
75 \r
76         if (ili9488_lcdMode == ILI9488_SPIMODE) {\r
77                 sBGR *p_buf = gpCanvasBuffer; \r
78                 if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);\r
79                 //it'd better change to a DMA transfer\r
80                 for(row = rc.y; row < h; row++) {\r
81                         for(col = rc.x; col < w; col++) {\r
82                                 //*p_buf++ = dwColor;\r
83                                 p_buf[row * gwCanvasMaxWidth + col].b = dwColor&0xFF;\r
84                                 p_buf[row * gwCanvasMaxWidth + col].g = dwColor>>8;\r
85                                 p_buf[row * gwCanvasMaxWidth + col].r = dwColor>>16;\r
86                         }\r
87                 }\r
88         } else {\r
89                 uint16_t *p_buf = gpCanvasBuffer;\r
90                 if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;\r
91                 //it'd better change to a DMA transfer\r
92                 for(row = rc.y; row < h; row++) {\r
93                         for(col = rc.x; col < w; col++) {\r
94                                 p_buf[row * gwCanvasMaxWidth + col] = (uint16_t)dwColor;\r
95                         }\r
96                 }\r
97         }\r
98 }\r
99 \r
100 /*----------------------------------------------------------------------------\r
101  *        Exported functions\r
102  *----------------------------------------------------------------------------*/\r
103 /*\r
104  * \brief Update windows size.\r
105  * \param rc  rectangle defines X and Y coordinate, width and height of windows.\r
106  */\r
107 void LCDD_SetUpdateWindowSize(rect rc)\r
108 {\r
109         gwCanvasMaxWidth = rc.width + 1;\r
110         gwCanvasMaxHeight = rc.height + 1;\r
111         if (ili9488_lcdMode == ILI9488_SPIMODE) {\r
112                 ILI9488_SpiSetWindow( rc.x, rc.y, rc.width, rc.height);\r
113         } else {\r
114                 ILI9488_EbiSetWindow( rc.x, rc.y, rc.width, rc.height);\r
115         }\r
116 }\r
117 \r
118 /*\r
119  * \brief Update windows in current canvas.\r
120  */\r
121 void LCDD_UpdateWindow(void)\r
122 {\r
123         uint32_t size = 0;\r
124         if (ili9488_lcdMode == ILI9488_SPIMODE) {\r
125                 size = gwCanvasBufferSize / (sizeof(sBGR)) *3 ;\r
126                 ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_WRITE, \r
127                                                 (uint8_t*)gpCanvasBuffer, 0, AccessWrite, size);\r
128         } else {\r
129                  size = gwCanvasBufferSize / sizeof(uint16_t);\r
130                  ILI9488_EbiSendCommand(ILI9488_CMD_MEMORY_WRITE, \r
131                                                 (uint16_t*)gpCanvasBuffer, 0, AccessWrite, size);\r
132         }\r
133  }\r
134 \r
135 /*\r
136  * \brief Update windows in partial canvas.\r
137  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
138  * \param size Size of canvas buffer.\r
139  */\r
140 void LCDD_UpdatePartialWindow(uint8_t* pCanvasBuffer,uint32_t size)\r
141 {\r
142         uint32_t cnt = 0;\r
143         if (ili9488_lcdMode == ILI9488_SPIMODE) {\r
144                 cnt = size/sizeof(sBGR) * 3;\r
145                 ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_WRITE, \r
146                                                 (uint8_t*)pCanvasBuffer, 0, AccessWrite, cnt);\r
147         } else {\r
148                  cnt = size/sizeof(uint16_t);\r
149                  ILI9488_EbiSendCommand(ILI9488_CMD_MEMORY_WRITE, \r
150                                                 (uint16_t*)pCanvasBuffer, 0, AccessWrite, cnt);\r
151         }\r
152 }\r
153 /*\r
154  * \brief Draws a rectangle with fill inside on LCD, at the given coordinates.\r
155  *\r
156  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
157  * \param x      X-coordinate of upper-left rectangle corner.\r
158  * \param y      Y-coordinate of upper-left rectangle corner.\r
159  * \param width  Rectangle width in pixels.\r
160  * \param height  Rectangle height in pixels.\r
161  * \param color  Rectangle color.\r
162  */\r
163 void LCDD_DrawRectangleWithFill(uint16_t *pCanvasBuffer, uint32_t dwX, uint32_t dwY, uint32_t dwWidth, \r
164                                 uint32_t dwHeight, uint32_t dwColor)\r
165 {\r
166         rect rc;\r
167         rc.x = dwX;\r
168         rc.y = dwY;\r
169         rc.width = dwWidth + 1;\r
170         rc.height = dwHeight + 1;\r
171         LCDD_FillSolidRect(pCanvasBuffer, rc , dwColor);\r
172 }\r
173 \r
174 /**\r
175  * \brief Draws a circle on LCD, at the given coordinates.\r
176  *\r
177  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
178  * \param x      X-coordinate of circle centre.\r
179  * \param y      Y-coordinate of circle centre.\r
180  * \param r      circle radius.\r
181  * \param color  circle color.\r
182  */\r
183 uint32_t LCDD_DrawCircle(uint16_t *pCanvasBuffer, uint32_t x, uint32_t y, uint32_t r, uint32_t color )\r
184 {\r
185         signed int d; /* Decision Variable */\r
186         uint32_t  curX; /* Current X Value */\r
187         uint32_t  curY; /* Current Y Value */\r
188 \r
189         d = 3 - (r << 1);\r
190         curX = 0;\r
191         curY = r;\r
192 \r
193         while (curX <= curY) {\r
194                 LCDD_DrawPixel(pCanvasBuffer, x + curX, y + curY, color);\r
195                 LCDD_DrawPixel(pCanvasBuffer, x + curX, y - curY, color);\r
196                 LCDD_DrawPixel(pCanvasBuffer, x - curX, y + curY, color);\r
197                 LCDD_DrawPixel(pCanvasBuffer, x - curX, y - curY, color);\r
198                 LCDD_DrawPixel(pCanvasBuffer, x + curY, y + curX, color);\r
199                 LCDD_DrawPixel(pCanvasBuffer, x + curY, y - curX, color);\r
200                 LCDD_DrawPixel(pCanvasBuffer, x - curY, y + curX, color);\r
201                 LCDD_DrawPixel(pCanvasBuffer, x - curY, y - curX, color);\r
202 \r
203                 if (d < 0) {\r
204                         d += (curX << 2) + 6;\r
205                 } else {\r
206                         d += ((curX - curY) << 2) + 10;\r
207                         curY--;\r
208                 }\r
209                 curX++;\r
210         }\r
211         return 0;\r
212 }\r
213 \r
214 /*\r
215  * \brief Draws a circle with fill inside on LCD, at the given coordinates.\r
216  *\r
217  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
218  * \param dwX      X-coordinate of upper-left rectangle corner.\r
219  * \param dwY      Y-coordinate of upper-left rectangle corner.\r
220  * \param dwRadius  Radius.\r
221  * \param color  Rectangle color.\r
222  */\r
223 uint32_t LCD_DrawFilledCircle(uint16_t *pCanvasBuffer, uint32_t dwX, uint32_t dwY, \r
224                                                 uint32_t dwRadius, uint32_t color)\r
225 {\r
226         signed int d; /* Decision Variable */\r
227         uint32_t dwCurX; /* Current X Value */\r
228         uint32_t dwCurY; /* Current Y Value */\r
229         uint32_t dwXmin, dwYmin;\r
230 \r
231         if (dwRadius == 0) {\r
232                 return 0;\r
233         }\r
234         d = 3 - (dwRadius << 1);\r
235         dwCurX = 0;\r
236         dwCurY = dwRadius;\r
237 \r
238         while ( dwCurX <= dwCurY ) {\r
239                 dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;\r
240                 dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;\r
241                 LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, dwYmin, \r
242                                                                         dwX + dwCurX - dwXmin, 1 ,color);\r
243                 LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, \r
244                                                                 dwY+dwCurY, dwX + dwCurX - dwXmin, 1,\r
245                                                 color );\r
246                 dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;\r
247                 dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;\r
248                 LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, dwYmin, \r
249                                                                 dwX + dwCurY -dwXmin , 1, color );\r
250                 LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, \r
251                                                                 dwY + dwCurX, dwX+dwCurY - dwXmin, 1,\r
252                                                 color  );\r
253                 if ( d < 0 ) {\r
254                         d += (dwCurX << 2) + 6;\r
255                 } else {\r
256                         d += ((dwCurX - dwCurY) << 2) + 10;\r
257                         dwCurY--;\r
258                 }\r
259                 dwCurX++;\r
260         }\r
261 \r
262         return 0;\r
263 }\r
264 \r
265 /**\r
266  * \brief Draws a string inside a LCD buffer, at the given coordinates.\r
267  *\r
268  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
269  * \param x        X-coordinate of string top-left corner.\r
270  * \param y        Y-coordinate of string top-left corner.\r
271  * \param pString  String to display.\r
272  * \param color    String color.\r
273  */\r
274 void LCDD_DrawString( uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, \r
275                      const uint8_t *pString, uint32_t color )\r
276 {\r
277         uint32_t xorg = x;\r
278 \r
279         while ( *pString != 0 ) {\r
280                 if ( *pString == '\n' ) {\r
281                         y += gFont.height + 2;\r
282                         x = xorg;\r
283                 } else {\r
284                         LCDD_DrawChar(pCanvasBuffer, x, y, *pString, color );\r
285                         x += gFont.width + 2;\r
286                 }\r
287                 pString++;\r
288         }\r
289 }\r
290 \r
291 /**\r
292  * \brief Returns the width & height in pixels that a string will occupy on the \r
293  * screen if drawn using LCDD_DrawString.\r
294  *\r
295  * \param pString  String.\r
296  * \param pWidth   Pointer for storing the string width (optional).\r
297  * \param pHeight  Pointer for storing the string height (optional).\r
298  *\r
299  * \return String width in pixels.\r
300  */\r
301 void LCDD_GetStringSize( const uint8_t *pString, uint32_t *pWidth,\r
302                                 uint32_t *pHeight )\r
303 {\r
304         uint32_t width = 0;\r
305         uint32_t height = gFont.height;\r
306 \r
307         while ( *pString != 0 ) {\r
308                 if ( *pString == '\n' ) {\r
309                         height += gFont.height + 2;\r
310                 } else {\r
311                         width += gFont.width + 2;\r
312                 }\r
313                 pString++;\r
314         }\r
315 \r
316         if ( width > 0 ) {\r
317                 width -= 2;\r
318         }\r
319 \r
320         if ( pWidth != NULL ) {\r
321                 *pWidth = width;\r
322         }\r
323 \r
324         if ( pHeight != NULL ) {\r
325                 *pHeight = height;\r
326         }\r
327 }\r
328 \r
329 \r
330 /*\r
331  * \brief Performs a bit-block transfer of the color data corresponding to a \r
332  * rectangle of pixels from the given source context into destination context.\r
333  *\r
334  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
335  * \param dst_x   X-coordinate of source rectangle.\r
336  * \param dst_y   Y-coordinate of source rectangle.\r
337  * \param dst_w   Rectangle width in pixels of source rectangle.\r
338  * \param dst_h   Rectangle height in pixels of source rectangle.\r
339  * \param src     Pointer to the source device context.\r
340  * \param src_x   X-coordinate of destination rectangle.\r
341  * \param src_y   Y-coordinate of destination rectangle.\r
342  * \param src_w   Rectangle width in pixels of destination rectangle.\r
343  * \param src_h   Rectangle height in pixels of destination rectangle.\r
344  */\r
345 void LCDD_BitBlt( uint16_t* pCanvasBuffer, uint32_t dst_x,uint32_t dst_y,uint32_t dst_w,uint32_t dst_h,\r
346                                  const LcdColor_t *src,\r
347                                  uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h)\r
348 {\r
349         uint32_t row,col;\r
350         uint32_t src_row,src_col;\r
351         //assert(gpCanvasBuffer!=NULL);\r
352         \r
353         src_h = src_h;\r
354         if (ili9488_lcdMode == ILI9488_SPIMODE) {\r
355                 sBGR *p_buf = gpCanvasBuffer;\r
356                 if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);\r
357                 //it'd better change to a DMA transfer\r
358                 SCB_CleanInvalidateDCache();\r
359                 for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {\r
360                         for(src_col = src_x,col = dst_x; col < dst_w; col++,src_col++) {\r
361                                 p_buf[row * gwCanvasMaxWidth+col].r = src[src_row*src_w + src_col]&0xFF;\r
362                                 p_buf[row * gwCanvasMaxWidth+col].g = src[src_row*src_w + src_col]>>8;\r
363                                 p_buf[row * gwCanvasMaxWidth+col].b = src[src_row*src_w + src_col]>>16;\r
364                         }\r
365                         memory_barrier()\r
366                 }\r
367                 memory_barrier()\r
368         } else {\r
369                 uint16_t *p_buf = gpCanvasBuffer;\r
370                 if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;\r
371                 //it'd better change to a DMA transfer\r
372                 SCB_CleanInvalidateDCache();\r
373                 for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {\r
374                         for(src_col = src_x, col = dst_x; col < dst_w; col++,src_col++) {\r
375                                 p_buf[row * gwCanvasMaxWidth+col] = src[src_row*src_w + src_col];\r
376                         }\r
377                 }\r
378                 memory_barrier()\r
379         }\r
380 }\r
381 \r
382 \r
383 /*\r
384  * \brief Performs a bit-block transfer of the color data corresponding to a \r
385  * rectangle of pixels from the given source context into destination context.\r
386  *\r
387  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
388  * \param dst_x   X-coordinate of source rectangle.\r
389  * \param dst_y   Y-coordinate of source rectangle.\r
390  * \param dst_w   Rectangle width in pixels of source rectangle.\r
391  * \param dst_h   Rectangle height in pixels of source rectangle.\r
392  * \param src     Pointer to the source device context.\r
393  * \param src_x   X-coordinate of destination rectangle.\r
394  * \param src_y   Y-coordinate of destination rectangle.\r
395  * \param src_w   Rectangle width in pixels of destination rectangle.\r
396  * \param src_h   Rectangle height in pixels of destination rectangle.\r
397  * \param alpha   alpha value.\r
398  */\r
399 void LCDD_BitBltAlphaBlend(uint16_t* pCanvasBuffer,\r
400                                                 uint32_t dst_x,\r
401                                                 uint32_t dst_y,\r
402                                                 uint32_t dst_w,\r
403                                                 uint32_t dst_h,\r
404                                                 const LcdColor_t *src,\r
405                                                 uint32_t src_x,\r
406                                                 uint32_t src_y,\r
407                                                 uint32_t src_w,\r
408                                                 uint32_t src_h,\r
409                                                 uint32_t alpha)\r
410 {\r
411         uint32_t row,col;\r
412         uint32_t src_row,src_col;\r
413         uint32_t w,h;\r
414         uint32_t dst_row;\r
415         uint32_t r,g,b;\r
416         \r
417         if (ili9488_lcdMode == ILI9488_SPIMODE) {\r
418                 sBGR *p_buf = gpCanvasBuffer;\r
419                 if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);\r
420 \r
421                 //it'd better change to a DMA transfer\r
422                 SCB_CleanInvalidateDCache();\r
423                 for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {\r
424                         for(src_col = src_x,col = dst_x; col < dst_w; col++,src_col++) {\r
425                                 p_buf[row *dst_w +col].r = src[src_row*src_w + src_col]&0xFF;\r
426                                 p_buf[row *dst_w +col].g = src[src_row*src_w + src_col]>>8;\r
427                                 p_buf[row *dst_w +col].b = src[src_row*src_w + src_col]>>16;\r
428                         }\r
429                 }\r
430                 memory_barrier()\r
431         } else {\r
432                 uint16_t *p_buf = gpCanvasBuffer;\r
433                 if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;\r
434                 w = src_x + src_w;\r
435                 h = src_y + src_h;\r
436                 dst_row = dst_y;\r
437                 p_buf += (dst_row*dst_w + dst_x);\r
438                 src += src_y*w + src_x;\r
439                 SCB_CleanInvalidateDCache();\r
440                 for(src_row = src_y; src_row < h; src_row++,dst_row++) {\r
441                         for(src_col = src_x; src_col < w; src_col++){\r
442                                 r = (p_buf[src_col] >> 11) * (255 - alpha) / 255 + \r
443                                                 (src[src_col] >> 11) * alpha / 255;\r
444                                 if(r > 0x1F) r = 0x1F;\r
445                                 g = ((p_buf[src_col] >> 5) & 0x3F) * (255 - alpha) / 255 + \r
446                                                 ((src[src_col] >> 5) & 0x3f) * alpha / 255;\r
447                                 if(g > 0x3F) g = 0x3F;\r
448                                 b = ((p_buf[src_col]) & 0x1F) * (255 - alpha) / 255 \r
449                                                 + ((src[src_col]) & 0x1f) * alpha / 255;\r
450                                 if(b > 0x1F) b = 0x1F;   \r
451                                 p_buf[src_col] = ((r & 0x1F) << 11)|((g & 0x3F) << 5)|( b & 0x1F);\r
452                         }\r
453                         p_buf += dst_w;\r
454                         src += w;\r
455                 }\r
456                 memory_barrier()\r
457         }\r
458 }\r
459 \r
460 /*\r
461  * \brief Draw a raw image at given position on LCD.\r
462  *\r
463  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
464  * \param dwX       X-coordinate of image start.\r
465  * \param dwY       Y-coordinate of image start.\r
466  * \param pImage    Image buffer.\r
467  * \param width     Image width.\r
468  * \param height    Image height.\r
469  */\r
470  void LCDD_DrawImage(uint16_t* pCanvasBuffer, uint32_t dwX, uint32_t dwY, \r
471                                         const LcdColor_t *pImage, uint32_t dwWidth, uint32_t dwHeight )\r
472 {\r
473         /* Determine the refresh window area */\r
474         /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */\r
475         //CheckBoxCoordinates(&dwX, &dwY, &dwWidth, &dwHeight);\r
476 \r
477         LCDD_BitBlt(pCanvasBuffer, dwX, dwY, dwWidth, dwHeight,\r
478                                 pImage, 0, 0, dwWidth - dwX, dwHeight - dwY);\r
479 }\r
480 \r
481 /**\r
482  * \brief Draw a pixel on LCD of given color.\r
483  *\r
484  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
485  * \param x  X-coordinate of pixel.\r
486  * \param y  Y-coordinate of pixel.\r
487  * \param color  Pixel color.\r
488  */\r
489 void LCDD_DrawPixel(uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, uint32_t color )\r
490 {\r
491         //assert(gpCanvasBuffer!=NULL);\r
492         if (ili9488_lcdMode == ILI9488_SPIMODE) {\r
493                 sBGR *p_buf = gpCanvasBuffer;\r
494                 if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);\r
495                 p_buf += y * gwCanvasMaxWidth;\r
496                 p_buf += x;\r
497                 p_buf->b = color&0xFF;\r
498                 p_buf->g = color>>8;\r
499                 p_buf->r = color>>16;\r
500                 p_buf++;\r
501                 memory_barrier()\r
502         } else {\r
503                 uint16_t *p_buf = gpCanvasBuffer;\r
504                 if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;\r
505                 p_buf += y * gwCanvasMaxWidth;\r
506                 p_buf += x;\r
507                 *p_buf = (uint16_t)color;\r
508         }\r
509 }\r
510 \r
511 /*\r
512  * \brief Draw a line on LCD, horizontal and vertical line are supported.\r
513  *\r
514  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
515  * \param dwX1   X-coordinate of line start.\r
516  * \param dwY1   Y-coordinate of line start.\r
517  * \param dwX2   X-coordinate of line end.\r
518  * \param dwY2   Y-coordinate of line end.\r
519  * \param color  Pixel color.\r
520  */\r
521 void LCDD_DrawLine(uint16_t* pCanvasBuffer, uint32_t dwX1, uint32_t dwY1, \r
522                                 uint32_t dwX2, uint32_t dwY2 , uint32_t color )\r
523 {\r
524         if (( dwY1 == dwY2 ) || (dwX1 == dwX2)) {\r
525                 //LCDD_DrawRectangleWithFill( dwX1, dwY1, dwX2, dwY2, color );\r
526                 LCDD_DrawStraightLine(pCanvasBuffer, dwX1, dwY1, dwX2, dwY2, color );\r
527         } else {\r
528                 LCDD_DrawLineBresenham(pCanvasBuffer, dwX1, dwY1, dwX2, dwY2 , color);\r
529         }\r
530 }\r
531 \r
532 void LCDD_DrawStraightLine(uint16_t* pCanvasBuffer, uint32_t dwX1, uint32_t dwY1, \r
533                                                 uint32_t dwX2, uint32_t dwY2 , uint32_t color )\r
534 {\r
535         uint32_t x,y;\r
536         uint32_t tmp;\r
537 \r
538         if(dwY1 > dwY2)\r
539         {\r
540                 tmp = dwY1;\r
541                 dwY1 = dwY2;\r
542                 dwY2 = tmp;\r
543         }\r
544         if(dwX1 > dwX2)\r
545         {\r
546                 tmp = dwX1;\r
547                 dwX1 = dwX2;\r
548                 dwX2 = tmp;\r
549         }\r
550         for(y = dwY1; y<=dwY2; y++)\r
551         {\r
552                 for(x=dwX1;x<=dwX2;x++)\r
553                 {\r
554                         LCDD_DrawPixel(pCanvasBuffer,  x , y , color);\r
555                 }\r
556         }\r
557 }\r
558 \r
559 /*\r
560  * \brief Draw a line on LCD, which is not horizontal or vertical.\r
561  *\r
562  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
563  * \param dwX1    X-coordinate of line start.\r
564  * \param dwY1    Y-coordinate of line start.\r
565  * \param dwX2    X-coordinate of line end.\r
566  * \param dwY2    Y-coordinate of line end.\r
567  * \param color   pixel color.\r
568  */\r
569 uint32_t LCDD_DrawLineBresenham(uint16_t* pCanvasBuffer, uint32_t dwX1, \r
570                                 uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 , uint32_t color)\r
571 {\r
572         int dx, dy;\r
573         int i;\r
574         int xinc, yinc, cumul;\r
575         int x, y;\r
576 \r
577         x = dwX1;\r
578         y = dwY1;\r
579         dx = dwX2 - dwX1;\r
580         dy = dwY2 - dwY1;\r
581 \r
582         xinc = ( dx > 0 ) ? 1 : -1;\r
583         yinc = ( dy > 0 ) ? 1 : -1;\r
584         dx = ( dx > 0 ) ? dx : -dx;\r
585         dy = ( dy > 0 ) ? dy : -dy;\r
586 \r
587         LCDD_DrawPixel(pCanvasBuffer, x , y , color);\r
588 \r
589         if ( dx > dy ) {\r
590                 cumul = dx / 2;\r
591                 for ( i = 1; i <= dx; i++ ) {\r
592                         x += xinc;\r
593                         cumul += dy;\r
594 \r
595                         if ( cumul >= dx ) {\r
596                                 cumul -= dx;\r
597                                 y += yinc;\r
598                         }\r
599                         LCDD_DrawPixel(pCanvasBuffer, x , y , color);\r
600                 }\r
601         } else {\r
602                 cumul = dy / 2;\r
603                 for ( i = 1; i <= dy; i++ ) {\r
604                         y += yinc;\r
605                         cumul += dx;\r
606 \r
607                         if ( cumul >= dy ) {\r
608                                 cumul -= dy;\r
609                                 x += xinc;\r
610                         }\r
611                         LCDD_DrawPixel(pCanvasBuffer, x , y , color);\r
612                 }\r
613         }\r
614 \r
615         return 0;\r
616 }\r
617 \r
618 /*\r
619  * \brief Draws a rectangle on LCD, at the given coordinates.\r
620  *\r
621  * \param pCanvasBuffer Pointer to dedicate canvas buffer.\r
622  * \param x      X-coordinate of upper-left rectangle corner.\r
623  * \param y      Y-coordinate of upper-left rectangle corner.\r
624  * \param width  Rectangle width in pixels.\r
625  * \param height Rectangle height in pixels.\r
626  * \param color  Rectangle color.\r
627  */\r
628 void LCDD_DrawRectangle(uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, \r
629                                         uint32_t width, uint32_t height, uint32_t color )\r
630 {\r
631         LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y, width, 1, color);\r
632         LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y, 1, height, color);\r
633 \r
634         LCDD_DrawRectangleWithFill(pCanvasBuffer, x + width , y, 1, height, color);\r
635         LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y + height, width, 1, color);\r
636 }\r
637 \r
638 /*\r
639  * \brief Set buffer for pCanvas.\r
640  *\r
641  * \param pCanvasBuffer  Pointer of external buffer.\r
642  * \param wBufferSize   Size of buffer.\r
643  */\r
644 void LCDD_SetCavasBuffer( void* pCanvasBuffer, uint32_t wBufferSize)\r
645 {\r
646         if (ili9488_lcdMode == ILI9488_SPIMODE) {\r
647                 gpCanvasBuffer = (sBGR*)pCanvasBuffer;\r
648                 gwCanvasBufferSize = wBufferSize;\r
649         } else {\r
650                 gpCanvasBuffer = (uint16_t*)pCanvasBuffer;\r
651                 gwCanvasBufferSize = wBufferSize;\r
652         }\r
653 }\r
654 \r
655 \r