1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2011, Atmel Corporation
\r
6 * All rights reserved.
\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
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\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
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
33 * Implementation of draw function on LCD, Include draw text, image
\r
34 * and basic shapes (line, rectangle, circle).
\r
38 /*----------------------------------------------------------------------------
\r
40 *----------------------------------------------------------------------------*/
\r
49 static LcdColor_t gLcdPixelCache[LCD_DATA_CACHE_SIZE];
\r
50 /*----------------------------------------------------------------------------
\r
51 * Exported functions
\r
52 *----------------------------------------------------------------------------*/
\r
56 * \brief Convert 24 bit RGB color into 5-6-5 rgb color space.
\r
58 * Initialize the LcdColor_t cache with the color pattern.
\r
59 * \param x 24-bits RGB color.
\r
60 * \return 0 for successfull operation.
\r
62 static uint32_t LCD_SetColor( uint32_t dwRgb24Bits )
\r
66 /* Fill the cache with selected color */
\r
67 for ( i = 0 ; i < LCD_DATA_CACHE_SIZE ; ++i )
\r
69 gLcdPixelCache[i] = dwRgb24Bits ;
\r
76 * \brief Check Box coordinates. Return upper left and bottom right coordinates.
\r
78 * \param pX1 X-coordinate of upper-left corner on LCD.
\r
79 * \param pY1 Y-coordinate of upper-left corner on LCD.
\r
80 * \param pX2 X-coordinate of lower-right corner on LCD.
\r
81 * \param pY2 Y-coordinate of lower-right corner on LCD.
\r
83 static void CheckBoxCoordinates( uint32_t *pX1, uint32_t *pY1, uint32_t *pX2, uint32_t *pY2 )
\r
87 if ( *pX1 >= BOARD_LCD_WIDTH )
\r
89 *pX1 = BOARD_LCD_WIDTH-1 ;
\r
91 if ( *pX2 >= BOARD_LCD_WIDTH )
\r
93 *pX2 = BOARD_LCD_WIDTH-1 ;
\r
95 if ( *pY1 >= BOARD_LCD_HEIGHT )
\r
97 *pY1 = BOARD_LCD_HEIGHT-1 ;
\r
99 if ( *pY2 >= BOARD_LCD_HEIGHT )
\r
101 *pY2 = BOARD_LCD_HEIGHT-1 ;
\r
117 * \brief Fills the given LCD buffer with a particular color.
\r
119 * \param color Fill color.
\r
121 void LCDD_Fill( uint32_t dwColor )
\r
125 // LCD_SetCursor( 0, 0 ) ;
\r
126 ILI9488_WriteRAM_Prepare() ;
\r
128 for ( dw = BOARD_LCD_WIDTH * BOARD_LCD_HEIGHT; dw > 0; dw-- )
\r
130 ILI9488_WriteRAM( dwColor ) ;
\r
135 * \brief Draw a pixel on LCD of given color.
\r
137 * \param x X-coordinate of pixel.
\r
138 * \param y Y-coordinate of pixel.
\r
139 * \param color Pixel color.
\r
141 extern void LCDD_DrawPixel( uint32_t x, uint32_t y, uint32_t color )
\r
143 ILI9488_SetCursor( x, y ) ;
\r
144 ILI9488_WriteRAM_Prepare() ;
\r
145 ILI9488_WriteRAM( color ) ;
\r
151 * \brief Read a pixel from LCD.
\r
153 * \param x X-coordinate of pixel.
\r
154 * \param y Y-coordinate of pixel.
\r
156 * \return color Readed pixel color.
\r
158 extern uint32_t LCDD_ReadPixel( uint32_t x, uint32_t y )
\r
162 ILI9488_SetCursor(x, y);
\r
163 ILI9488_ReadRAM_Prepare();
\r
164 color = ILI9488_ReadRAM();
\r
170 * \brief Draw a line on LCD, horizontal and vertical line are supported.
\r
172 * \param x X-coordinate of line start.
\r
173 * \param y Y-coordinate of line start.
\r
174 * \param length line length.
\r
175 * \param direction line direction: 0 - horizontal, 1 - vertical.
\r
176 * \param color Pixel color.
\r
178 extern void LCDD_DrawLine( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 , uint32_t color )
\r
180 if (( dwY1 == dwY2 ) || (dwX1 == dwX2))
\r
182 LCDD_DrawRectangleWithFill( dwX1, dwY1, dwX2, dwY2, color );
\r
186 LCDD_DrawLineBresenham( dwX1, dwY1, dwX2, dwY2 , color) ;
\r
194 * \brief Draw a line on LCD, which is not horizontal or vertical.
\r
196 * \param x X-coordinate of line start.
\r
197 * \param y Y-coordinate of line start.
\r
198 * \param length line length.
\r
199 * \param direction line direction: 0 - horizontal, 1 - vertical.
\r
200 * \param color LcdColor_t color.
\r
202 extern uint32_t LCDD_DrawLineBresenham( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 , uint32_t color)
\r
206 int xinc, yinc, cumul ;
\r
214 xinc = ( dx > 0 ) ? 1 : -1 ;
\r
215 yinc = ( dy > 0 ) ? 1 : -1 ;
\r
216 dx = ( dx > 0 ) ? dx : -dx ;
\r
217 dy = ( dy > 0 ) ? dy : -dy ;
\r
219 LCDD_DrawPixel(x , y , color);
\r
224 for ( i = 1 ; i <= dx ; i++ )
\r
234 LCDD_DrawPixel(x , y , color);
\r
240 for ( i = 1 ; i <= dy ; i++ )
\r
251 LCDD_DrawPixel(x , y , color);
\r
259 * \brief Draws a rectangle on LCD, at the given coordinates.
\r
261 * \param x X-coordinate of upper-left rectangle corner.
\r
262 * \param y Y-coordinate of upper-left rectangle corner.
\r
263 * \param width Rectangle width in pixels.
\r
264 * \param height Rectangle height in pixels.
\r
265 * \param color Rectangle color.
\r
267 extern void LCDD_DrawRectangle( uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color )
\r
270 LCDD_DrawRectangleWithFill(x, y, width, y, color);
\r
271 LCDD_DrawRectangleWithFill(x, height, width, height, color);
\r
273 LCDD_DrawRectangleWithFill(x, y, x, height, color);
\r
274 LCDD_DrawRectangleWithFill(width, y, width, height, color);
\r
278 * \brief Draws a rectangle with fill inside on LCD, at the given coordinates.
\r
280 * \param x X-coordinate of upper-left rectangle corner.
\r
281 * \param y Y-coordinate of upper-left rectangle corner.
\r
282 * \param width Rectangle width in pixels.
\r
283 * \param height Rectangle height in pixels.
\r
284 * \param color Rectangle color.
\r
286 extern void LCDD_DrawRectangleWithFill( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwColor )
\r
288 uint32_t size, blocks;
\r
290 CheckBoxCoordinates(&dwX, &dwY, &dwWidth, &dwHeight);
\r
291 LCD_SetColor(dwColor);
\r
292 ILI9488_SetWindow( dwX, dwY, dwWidth, dwHeight ) ;
\r
294 size = (dwWidth - dwX + 1) * (dwHeight - dwY + 1);
\r
296 /* Send pixels blocks => one LCD IT / block */
\r
297 blocks = size / LCD_DATA_CACHE_SIZE;
\r
299 ILI9488_WriteRAM_Prepare() ;
\r
303 ILI9488_WriteRAMBuffer(gLcdPixelCache, LCD_DATA_CACHE_SIZE);
\r
305 /* Send remaining pixels */
\r
306 ILI9488_WriteRAMBuffer(gLcdPixelCache, size % LCD_DATA_CACHE_SIZE);
\r
307 ILI9488_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
\r
308 // LCD_SetCursor( 0, 0 ) ;
\r
312 * \brief Draws a circle on LCD, at the given coordinates.
\r
314 * \param x X-coordinate of circle center.
\r
315 * \param y Y-coordinate of circle center.
\r
316 * \param r circle radius.
\r
317 * \param color circle color.
\r
319 extern uint32_t LCDD_DrawCircle( uint32_t x, uint32_t y, uint32_t r, uint32_t color )
\r
321 signed int d; /* Decision Variable */
\r
322 uint32_t curX; /* Current X Value */
\r
323 uint32_t curY; /* Current Y Value */
\r
329 while (curX <= curY)
\r
331 LCDD_DrawPixel(x + curX, y + curY, color);
\r
332 LCDD_DrawPixel(x + curX, y - curY, color);
\r
333 LCDD_DrawPixel(x - curX, y + curY, color);
\r
334 LCDD_DrawPixel(x - curX, y - curY, color);
\r
335 LCDD_DrawPixel(x + curY, y + curX, color);
\r
336 LCDD_DrawPixel(x + curY, y - curX, color);
\r
337 LCDD_DrawPixel(x - curY, y + curX, color);
\r
338 LCDD_DrawPixel(x - curY, y - curX, color);
\r
341 d += (curX << 2) + 6;
\r
344 d += ((curX - curY) << 2) + 10;
\r
353 extern uint32_t LCD_DrawFilledCircle( uint32_t dwX, uint32_t dwY, uint32_t dwRadius, uint32_t color)
\r
355 signed int d ; /* Decision Variable */
\r
356 uint32_t dwCurX ; /* Current X Value */
\r
357 uint32_t dwCurY ; /* Current Y Value */
\r
358 uint32_t dwXmin, dwYmin;
\r
364 d = 3 - (dwRadius << 1) ;
\r
366 dwCurY = dwRadius ;
\r
368 while ( dwCurX <= dwCurY )
\r
370 dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;
\r
371 dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;
\r
372 LCDD_DrawRectangleWithFill( dwXmin, dwYmin, dwX+dwCurX, dwYmin ,color) ;
\r
373 LCDD_DrawRectangleWithFill( dwXmin, dwY+dwCurY, dwX+dwCurX, dwY+dwCurY, color ) ;
\r
374 dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;
\r
375 dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;
\r
376 LCDD_DrawRectangleWithFill( dwXmin, dwYmin, dwX+dwCurY, dwYmin, color ) ;
\r
377 LCDD_DrawRectangleWithFill( dwXmin, dwY+dwCurX, dwX+dwCurY, dwY+dwCurX, color ) ;
\r
381 d += (dwCurX << 2) + 6 ;
\r
385 d += ((dwCurX - dwCurY) << 2) + 10;
\r
395 * \brief Draws a string inside a LCD buffer, at the given coordinates. Line breaks
\r
398 * \param x X-coordinate of string top-left corner.
\r
399 * \param y Y-coordinate of string top-left corner.
\r
400 * \param pString String to display.
\r
401 * \param color String color.
\r
403 extern void LCDD_DrawString( uint32_t x, uint32_t y, const uint8_t *pString, uint32_t color )
\r
405 uint32_t xorg = x ;
\r
407 while ( *pString != 0 )
\r
409 if ( *pString == '\n' )
\r
411 y += gFont.height + 2 ;
\r
416 LCDD_DrawChar( x, y, *pString, color ) ;
\r
417 x += gFont.width + 2 ;
\r
425 * \brief Draws a string inside a LCD buffer, at the given coordinates
\r
426 * with given background color. Line breaks will be honored.
\r
428 * \param x X-coordinate of string top-left corner.
\r
429 * \param y Y-coordinate of string top-left corner.
\r
430 * \param pString String to display.
\r
431 * \param fontColor String color.
\r
432 * \param bgColor Background color.
\r
434 extern void LCDD_DrawStringWithBGColor( uint32_t x, uint32_t y, const char *pString, uint32_t fontColor, uint32_t bgColor )
\r
438 while ( *pString != 0 )
\r
440 if ( *pString == '\n' )
\r
442 y += gFont.height + 2 ;
\r
447 LCDD_DrawCharWithBGColor( x, y, *pString, fontColor, bgColor ) ;
\r
448 x += gFont.width + 2;
\r
456 * \brief Returns the width & height in pixels that a string will occupy on the screen
\r
457 * if drawn using LCDD_DrawString.
\r
459 * \param pString String.
\r
460 * \param pWidth Pointer for storing the string width (optional).
\r
461 * \param pHeight Pointer for storing the string height (optional).
\r
463 * \return String width in pixels.
\r
465 extern void LCDD_GetStringSize( const uint8_t *pString, uint32_t *pWidth, uint32_t *pHeight )
\r
467 uint32_t width = 0;
\r
468 uint32_t height = gFont.height;
\r
470 while ( *pString != 0 )
\r
472 if ( *pString == '\n' )
\r
474 height += gFont.height + 2 ;
\r
478 width += gFont.width + 2 ;
\r
489 if ( pWidth != NULL )
\r
494 if ( pHeight != NULL )
\r
496 *pHeight = height ;
\r
501 * \brief Draw a raw image at given position on LCD.
\r
503 * \param x X-coordinate of image start.
\r
504 * \param y Y-coordinate of image start.
\r
505 * \param pImage Image buffer.
\r
506 * \param width Image width.
\r
507 * \param height Image height.
\r
509 extern void LCDD_DrawImage( uint32_t dwX, uint32_t dwY, const LcdColor_t *pImage, uint32_t dwWidth, uint32_t dwHeight )
\r
514 /* Determine the refresh window area */
\r
515 /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
\r
516 CheckBoxCoordinates(&dwX, &dwY, &dwWidth, &dwHeight);
\r
517 ILI9488_SetWindow(dwX, dwY, dwWidth, dwHeight);
\r
519 /* Prepare to write in GRAM */
\r
520 ILI9488_WriteRAM_Prepare();
\r
522 size = (dwWidth - dwX + 1) * (dwHeight - dwY + 1);
\r
524 ILI9488_WriteRAMBuffer(pImage, size);
\r
526 ILI9488_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
\r
530 * \brief Draw a raw image at given position on LCD.
\r
532 * \param dwX X-coordinate of image start.
\r
533 * \param dwY Y-coordinate of image start.
\r
534 * \param pGIMPImage Image data.
\r
536 void LCDD_DrawGIMPImage( uint32_t dwX, uint32_t dwY, const SGIMPImage* pGIMPImage )
\r
539 register uint32_t dwLength ;
\r
543 // Draw raw RGB bitmap
\r
544 // CheckBoxCoordinates(&dwX, &dwY, &dwWidth, &dwHeight);
\r
545 ILI9488_SetWindow( dwX, dwY, pGIMPImage->dwWidth, pGIMPImage->dwHeight ) ;
\r
546 // LCD_SetCursor( dwX, dwY ) ;
\r
548 ILI9488_WriteRAM_Prepare() ;
\r
550 dwLength = pGIMPImage->dwWidth*pGIMPImage->dwHeight ;
\r
551 pucData = pGIMPImage->pucPixel_data ;
\r
552 for ( dw=0; dw < dwLength; dw++ )
\r
554 *pData = ((*pucData++)<<16) ;
\r
555 *pData |= ((*pucData++)<<8) ;
\r
556 *pData |= (*pucData++) ;
\r
557 ILI9488_WriteRAM(*pData);
\r
560 ILI9488_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
\r
564 * \brief Clear a window with an color.
\r
566 * \param dwX X-coordinate of the window.
\r
567 * \param dwY Y-coordinate of the window.
\r
568 * \param dwWidth window width.
\r
569 * \param dwHeight window height.
\r
570 * \param dwColor background color
\r
572 extern void LCDD_ClearWindow( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwColor )
\r
577 ILI9488_SetWindow( dwX, dwY, dwWidth, dwHeight ) ;
\r
578 ILI9488_WriteRAM_Prepare() ;
\r
580 for ( dw = dwWidth * dwHeight; dw > 0; dw-- )
\r
582 ILI9488_WriteRAM( dwColor ) ;
\r