diff --git a/halext/drivers/gdispNokia6100/gdisp_lld.h b/halext/drivers/gdispNokia6100/gdisp_lld.h index dfdb1ad5..55241715 100644 --- a/halext/drivers/gdispNokia6100/gdisp_lld.h +++ b/halext/drivers/gdispNokia6100/gdisp_lld.h @@ -35,8 +35,8 @@ */ /** - * @file gdispNokia6100/gdisp_lld.h - * @brief GDISP Graphic Driver subsystem low level driver header for the Nokia6100 display. + * @file templates/gdisp_lld.h + * @brief GDISP Graphic Driver subsystem low level driver header template. * * @addtogroup GDISP * @{ @@ -93,7 +93,6 @@ struct GDISPDriver { #if defined(GDISP_DRIVER_EXT_FIELDS) GDISP_DRIVER_EXT_FIELDS #endif - /* End of mandatory fields */ }; @@ -106,7 +105,7 @@ struct GDISPDriver { /*===========================================================================*/ #if !defined(__DOXYGEN__) - extern GDISPDriver GDISP1; + extern GDISPDriver GDISP; #endif #ifdef __cplusplus @@ -119,7 +118,7 @@ extern "C" { void gdisp_lld_setorientation(gdisp_orientation_t newOrientation); /* Some of these functions will be implemented in software by the high level driver - depending on the GDISP_HARDWARE_XXX macros defined above. + depending on the GDISP_HARDWARE_XXX macros defined in gdisp_lld_config.h. */ /* Drawing functions */ diff --git a/halext/drivers/gdispNokia6100/readme.txt b/halext/drivers/gdispNokia6100/readme.txt new file mode 100644 index 00000000..35338eaa --- /dev/null +++ b/halext/drivers/gdispNokia6100/readme.txt @@ -0,0 +1,12 @@ +To use this driver: + +1. Add in your halconf.h: + a) #define HAL_USE_GDISP TRUE + b) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD + c) One (only) of: + #define LCD_USE_GE8 + #define LCD_USE_GE12 + +2. To your makefile add the following lines: + include $(CHIBIOS)/os/halext/halext.mk + include $(CHIBIOS)/os/halext/drivers/gdispSsd1289/gdisp_lld.mk diff --git a/halext/drivers/gdispS6d1121/gdisp_lld.c b/halext/drivers/gdispS6d1121/gdisp_lld.c new file mode 100644 index 00000000..fdf7dce9 --- /dev/null +++ b/halext/drivers/gdispS6d1121/gdisp_lld.c @@ -0,0 +1,695 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + --- + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes ChibiOS/RT, without being obliged to provide + the source code for any proprietary components. See the file exception.txt + for full details of how and when the exception can be applied. +*/ +/* + Concepts and parts of this file have been contributed by: + Joel Bodenmann aka Tectu -> Maintainer + Andrew Hannam aka inmarket -> framework + Badger -> console implementation and FSMC + Abhishek -> font rendering + Ben William -> fastMath and lcdDrawEllipse() + Dongxu Li aka dxli -> lcdDrawEllipse() filled option +*/ + +/** + * @file gdispS6d1121/gdisp_lld.c + * @brief GDISP Graphics Driver subsystem low level driver source for the S6d1121 display. + * + * @addtogroup GDISP + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "gdisp.h" +#include "gdisp_fonts.h" + +#if HAL_USE_GDISP || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#ifdef UNUSED +#elif defined(__GNUC__) +# define UNUSED(x) UNUSED_ ## x __attribute__((unused)) +#elif defined(__LCLINT__) +# define UNUSED(x) /*@unused@*/ x +#else +# define UNUSED(x) x +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) + GDISPDriver GDISP; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +#include "s6d1121_lld.c.h" + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/* Include the software emulation routines */ +#include "gdisp_lld_inc_emulation.c.h" + +/* ---- Required Routines ---- */ +/* + The following 2 routines are required. + All other routines are optional. +*/ + +/** + * @brief Low level GDISP driver initialization. + * + * @notapi + */ +void gdisp_lld_init(void) { + palSetPadMode(LCD_RST_GPIO, LCD_RST_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + // A Good idea to reset the module before using + LCD_RST_LOW; + s6d1121_delay(2); + LCD_RST_HIGH; // Hardware Reset + s6d1121_delay(2); + + #ifdef LCD_USE_GPIO + // IO Default Configurations + palSetPadMode(LCD_CS_GPIO, LCD_CS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + palSetPadMode(LCD_WR_GPIO, LCD_WR_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + palSetPadMode(LCD_RD_GPIO, LCD_RD_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + palSetPadMode(LCD_RS_GPIO, LCD_RS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + palSetPadMode(LCD_BL_GPIO, LCD_BL_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + + palSetGroupMode(LCD_D0_GPIO, 0x0000000F, 0, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + palSetGroupMode(LCD_D4_GPIO, 0x0000FFF0, 0, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + + LCD_CS_HIGH; + LCD_RD_HIGH; + LCD_WR_HIGH; + LCD_BL_LOW; + + #elif defined(LCD_USE_FSMC) + #if defined(STM32F1XX) + /* FSMC setup. TODO: this only works for STM32F1 */ + rccEnableAHB(RCC_AHBENR_FSMCEN, 0); + + /* TODO: pin setup */ + #elif defined(STM32F4XX) + /* STM32F4 FSMC init */ + rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); + + /* set pins to FSMC mode */ + IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) | + (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0}; + + IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | + (1 << 13) | (1 << 14) | (1 << 15), 0}; + + palSetBusMode(&busD, PAL_MODE_ALTERNATE(12)); + palSetBusMode(&busE, PAL_MODE_ALTERNATE(12)); + #else + #error "FSMC not implemented for this device" + #endif + + int FSMC_Bank = 0; + /* FSMC timing */ + FSMC_Bank1->BTCR[FSMC_Bank+1] = (10) | (10 << 8) | (10 << 16); + + /* Bank1 NOR/SRAM control register configuration */ + FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; + #endif + + lld_lcdWriteReg(0x11,0x2004); + lld_lcdWriteReg(0x13,0xCC00); + lld_lcdWriteReg(0x15,0x2600); + lld_lcdWriteReg(0x14,0x252A); + lld_lcdWriteReg(0x12,0x0033); + lld_lcdWriteReg(0x13,0xCC04); + + s6d1121_delay(1); + + lld_lcdWriteReg(0x13,0xCC06); + + s6d1121_delay(1); + + lld_lcdWriteReg(0x13,0xCC4F); + + s6d1121_delay(1); + + lld_lcdWriteReg(0x13,0x674F); + lld_lcdWriteReg(0x11,0x2003); + + s6d1121_delay(1); + + // Gamma Setting + lld_lcdWriteReg(0x30,0x2609); + lld_lcdWriteReg(0x31,0x242C); + lld_lcdWriteReg(0x32,0x1F23); + lld_lcdWriteReg(0x33,0x2425); + lld_lcdWriteReg(0x34,0x2226); + lld_lcdWriteReg(0x35,0x2523); + lld_lcdWriteReg(0x36,0x1C1A); + lld_lcdWriteReg(0x37,0x131D); + lld_lcdWriteReg(0x38,0x0B11); + lld_lcdWriteReg(0x39,0x1210); + lld_lcdWriteReg(0x3A,0x1315); + lld_lcdWriteReg(0x3B,0x3619); + lld_lcdWriteReg(0x3C,0x0D00); + lld_lcdWriteReg(0x3D,0x000D); + + lld_lcdWriteReg(0x16,0x0007); + lld_lcdWriteReg(0x02,0x0013); + lld_lcdWriteReg(0x03,0x0003); + lld_lcdWriteReg(0x01,0x0127); + + s6d1121_delay(1); + + lld_lcdWriteReg(0x08,0x0303); + lld_lcdWriteReg(0x0A,0x000B); + lld_lcdWriteReg(0x0B,0x0003); + lld_lcdWriteReg(0x0C,0x0000); + lld_lcdWriteReg(0x41,0x0000); + lld_lcdWriteReg(0x50,0x0000); + lld_lcdWriteReg(0x60,0x0005); + lld_lcdWriteReg(0x70,0x000B); + lld_lcdWriteReg(0x71,0x0000); + lld_lcdWriteReg(0x78,0x0000); + lld_lcdWriteReg(0x7A,0x0000); + lld_lcdWriteReg(0x79,0x0007); + lld_lcdWriteReg(0x07,0x0051); + + s6d1121_delay(1); + + lld_lcdWriteReg(0x07,0x0053); + lld_lcdWriteReg(0x79,0x0000); + + lld_lcdResetViewPort(); + + /* Now initialise the GDISP structure */ + GDISP.Width = SCREEN_WIDTH; + GDISP.Height = SCREEN_HEIGHT; + GDISP.Orientation = portrait; + GDISP.Powermode = powerOn; +} + +/** + * @brief Draws a pixel on the display. + * + * @param[in] x X location of the pixel + * @param[in] y Y location of the pixel + * @param[in] color The color of the pixel + * + * @notapi + */ +void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { + #if GDISP_NEED_VALIDATION + if (x >= GDISP.Width || y >= GDISP.Height) return; + #endif + lld_lcdSetCursor(x, y); + lld_lcdWriteReg(0x0022, color); +} + +/* ---- Optional Routines ---- */ +/* + All the below routines are optional. + Defining them will increase speed but everything + will work if they are not defined. + If you are not using a routine - turn it off using + the appropriate GDISP_HARDWARE_XXXX macro. + Don't bother coding for obvious similar routines if + there is no performance penalty as the emulation software + makes a good job of using similar routines. + eg. If gdisp_lld_fillarea() is defined there is little + point in defining gdisp_lld_clear() unless the + performance bonus is significant. + For good performance it is suggested to implement + gdisp_lld_fillarea() and gdisp_lld_blitarea(). +*/ + +#if GDISP_HARDWARE_POWERCONTROL || defined(__DOXYGEN__) +/** + * @brief Sets the power mode for the graphic device. + * @note The power modes are powerOn, powerSleep and powerOff. + * If powerSleep is not supported it is equivalent to powerOn. + * + * @param[in] powerMode The new power mode + * + * @notapi + */ + void gdisp_lld_setpowermode(gdisp_powermode_t powerMode) { + if (GDISP.Powermode == powerMode) + return; + + switch(powerMode) { + case powerOff: + /* Code here */ + break; + case powerOn: + /* Code here */ + /* You may need this --- + if (GDISP.Powermode != powerSleep) + gdisp_lld_init(); + */ + break; + case powerSleep: + /* Code here */ + break; + default: + return; + } + + GDISP.Powermode = powerMode; + } +#endif + +#if GDISP_HARDWARE_ORIENTATION || defined(__DOXYGEN__) + /** + * @brief Sets the orientation of the display. + * @note This may be ignored if not supported by the device. + * + * @param[in] newOrientation The new orientation + * + * @notapi + */ + void gdisp_lld_setorientation(gdisp_orientation_t newOrientation) { + if (GDISP.Orientation == newOrientation) + return; + + switch(newOrientation) { + case portrait: + lld_lcdWriteReg(0x0001,0x0127); + lld_lcdWriteReg(0x03, 0b0011); + GDISP.Height = SCREEN_HEIGHT; + GDISP.Width = SCREEN_WIDTH; + break; + case landscape: + lld_lcdWriteReg(0x0001,0x0027); + lld_lcdWriteReg(0x0003, 0b1011); + GDISP.Height = SCREEN_WIDTH; + GDISP.Width = SCREEN_HEIGHT; + break; + case portraitInv: + lld_lcdWriteReg(0x0001,0x0127); + lld_lcdWriteReg(0x0003, 0b0000); + GDISP.Height = SCREEN_HEIGHT; + GDISP.Width = SCREEN_WIDTH; + break; + case landscapeInv: + lld_lcdWriteReg(0x0001,0x0027); + lld_lcdWriteReg(0x0003, 0b1000); + GDISP.Height = SCREEN_WIDTH; + GDISP.Width = SCREEN_HEIGHT; + break; + default: + return; + } + GDISP.Orientation = newOrientation; + } +#endif + +#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__) + /** + * @brief Clear the display. + * @note Optional - The high level driver can emulate using software. + * + * @param[in] color The color of the pixel + * + * @notapi + */ + void gdisp_lld_clear(color_t color) { + unsigned i; + + lld_lcdSetCursor(0, 0); + lld_lcdWriteStreamStart(); + + for(i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) + lld_lcdWriteData(color); + + lld_lcdWriteStreamStop(); + } +#endif + +#if GDISP_HARDWARE_LINES || defined(__DOXYGEN__) + /** + * @brief Draw a line. + * @note Optional - The high level driver can emulate using software. + * + * @param[in] x0, y0 The start of the line + * @param[in] x1, y1 The end of the line + * @param[in] color The color of the line + * + * @notapi + */ + void gdisp_lld_drawline(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) { + #if GDISP_NEED_VALIDATION + /* Need to clip to screen */ + #endif + /* Code here */ + } +#endif + +#if GDISP_HARDWARE_BOX || defined(__DOXYGEN__) + /** + * @brief Draw a box. + * @pre The GDISP unit must be in powerOn or powerSleep mode. + * + * @param[in] x0,y0 The start position + * @param[in] cx,cy The size of the box (outside dimensions) + * @param[in] color The color to use + * @param[in] filled Should the box should be filled + * + * @notapi + */ + void gdisp_lld_drawbox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { + #if GDISP_NEED_VALIDATION + /* Need to clip to screen */ + #endif + /* Code here */ + } +#endif + +#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) + /** + * @brief Fill an area with a color. + * @note Optional - The high level driver can emulate using software. + * + * @param[in] x, y The start filled area + * @param[in] cx, cy The width and height to be filled + * @param[in] color The color of the fill + * + * @notapi + */ + void gdisp_lld_fillarea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { + #if GDISP_NEED_VALIDATION + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) cx = GDISP.Width - x; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; + #endif + + unsigned i, area; + + area = cx*cy; + lld_lcdSetViewPort(x, y, cx, cy); + lld_lcdWriteStreamStart(); + for(i = 0; i < area; i++) + lld_lcdWriteData(color); + lld_lcdWriteStreamStop(); + lld_lcdResetViewPort(); + } +#endif + +#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__) + /** + * @brief Fill an area with a bitmap. + * @note Optional - The high level driver can emulate using software. + * + * @param[in] x, y The start filled area + * @param[in] cx, cy The width and height to be filled + * @param[in] buffer The pixels to use to fill the area. + * + * @notapi + */ + void gdisp_lld_blitarea(coord_t x, coord_t y, coord_t cx, coord_t cy, pixel_t *buffer) { + unsigned i, area; + + #if GDISP_NEED_VALIDATION + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) return; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; + #endif + + area = cx*cy; + lld_lcdSetViewPort(x, y, cx, cy); + lld_lcdWriteStreamStart(); + for(i = 0; i < area; i++) + lld_lcdWriteData(*buffer++); + lld_lcdWriteStreamStop(); + lld_lcdResetViewPort(); + } +#endif + +/* Circular Drawing Functions */ +#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLES) || defined(__DOXYGEN__) + /** + * @brief Draw a circle. + * @note Optional - The high level driver can emulate using software. + * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave + * correctly if the circle is over the edges of the screen. + * + * @param[in] x, y The centre of the circle + * @param[in] radius The radius of the circle + * @param[in] color The color of the circle + * + * @notapi + */ + void gdisp_lld_drawcircle(coord_t x, coord_t y, coord_t radius, color_t color) { + #if GDISP_NEED_VALIDATION + /* Code here */ + #endif + /* Code here */ + } +#endif + +#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLEFILLS) || defined(__DOXYGEN__) + /** + * @brief Create a filled circle. + * @note Optional - The high level driver can emulate using software. + * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave + * correctly if the circle is over the edges of the screen. + * + * @param[in] x, y The centre of the circle + * @param[in] radius The radius of the circle + * @param[in] color The color of the circle + * + * @notapi + */ + void gdisp_lld_fillcircle(coord_t x, coord_t y, coord_t radius, color_t color) { + #if GDISP_NEED_VALIDATION + /* Code here */ + #endif + /* Code here */ + } +#endif + +#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSES) || defined(__DOXYGEN__) + /** + * @brief Draw an ellipse. + * @note Optional - The high level driver can emulate using software. + * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave + * correctly if the ellipse is over the edges of the screen. + * + * @param[in] x, y The centre of the ellipse + * @param[in] a, b The dimensions of the ellipse + * @param[in] color The color of the ellipse + * + * @notapi + */ + void gdisp_lld_drawellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { + #if GDISP_NEED_VALIDATION + /* Code here */ + #endif + /* Code here */ + } +#endif + +#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSEFILLS) || defined(__DOXYGEN__) + /** + * @brief Create a filled ellipse. + * @note Optional - The high level driver can emulate using software. + * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave + * correctly if the ellipse is over the edges of the screen. + * + * @param[in] x, y The centre of the ellipse + * @param[in] a, b The dimensions of the ellipse + * @param[in] color The color of the ellipse + * + * @notapi + */ + void gdisp_lld_fillellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { + #if GDISP_NEED_VALIDATION + /* Code here */ + #endif + /* Code here */ + } +#endif + +#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) + /** + * @brief Draw a character using a transparent background. + * @note Optional - The high level driver can emulate using software. + * + * @param[in] x, y The top-left corner of the text + * @param[in] c The character to print + * @param[in] color The color of the character + * + * @notapi + */ + void gdisp_lld_drawchar(coord_t x, coord_t y, char c, font_t font, color_t color) { + #if GDISP_NEED_VALIDATION + /* Code here */ + #endif + /* Code here */ + } +#endif + +#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXTFILLS) || defined(__DOXYGEN__) + /** + * @brief Draw a character using a filled background. + * @note Optional - The high level driver can emulate using software. + * + * @param[in] x, y The top-left corner of the text + * @param[in] c The character to print + * @param[in] color The color of the character + * @param[in] bgcolor The background color + * + * @notapi + */ + void gdisp_lld_fillchar(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor) { + #if GDISP_NEED_VALIDATION + /* Code here */ + #endif + /* Code here */ + } +#endif + +#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__) + /** + * @brief Get the color of a particular pixel. + * @note Optional. + * @note If x,y is off the screen, the result is undefined. + * + * @param[in] x, y The start of the text + * + * @notapi + */ + color_t gdisp_lld_getpixelcolor(coord_t x, coord_t y) { + /* This routine is marked "DO NOT USE" in the original + * GLCD driver. We just keep our GDISP_HARDWARE_READPIXEL + * turned off for now. + */ + color_t color; + + #if GDISP_NEED_VALIDATION + if (x >= GDISP.Width || y >= GDISP.Height) return 0; + #endif + + lld_lcdSetCursor(x, y); + lld_lcdWriteStreamStart(); + + color = lld_lcdReadData(); + color = lld_lcdReadData(); + + lld_lcdWriteStreamStop(); + + return color; + } +#endif + +#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__) + /** + * @brief Scroll vertically a section of the screen. + * @note Optional. + * @note If x,y + cx,cy is off the screen, the result is undefined. + * @note If lines is >= cy, it is equivelent to a area fill with bgcolor. + * + * @param[in] x, y The start of the area to be scrolled + * @param[in] cx, cy The size of the area to be scrolled + * @param[in] lines The number of lines to scroll (Can be positive or negative) + * @param[in] bgcolor The color to fill the newly exposed area. + * + * @notapi + */ + void gdisp_lld_verticalscroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) { + /* This is marked as "TODO: Test this" in the original GLCD driver. + * For now we just leave the GDISP_HARDWARE_SCROLL off. + */ + static color_t buf[((SCREEN_HEIGHT > SCREEN_WIDTH ) ? SCREEN_HEIGHT : SCREEN_WIDTH)]; + coord_t row0, row1; + unsigned i, gap, abslines; + + abslines = lines < 0 ? -lines : lines; + + #if GDISP_NEED_VALIDATION + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) cx = GDISP.Width - x; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; + #endif + + if (!abslines) return; + if (abslines >= cy) { + abslines = cy; + gap = 0; + } else { + gap = cy - abslines; + for(i = 0; i < gap; i++) { + if(lines > 0) { + row0 = y + i + lines; + row1 = y + i; + } else { + row0 = (y - i - 1) + lines; + row1 = (y - i - 1); + } + + /* read row0 into the buffer and then write at row1*/ + lld_lcdSetViewPort(x, row0, cx, 1); + lld_lcdReadStreamStart(); + lld_lcdReadStream(buf, cx); + lld_lcdReadStreamStop(); + + lld_lcdSetViewPort(x, row1, cx, 1); + lld_lcdWriteStreamStart(); + lld_lcdWriteStream(buf, cx); + lld_lcdWriteStreamStop(); + } + } + + /* fill the remaining gap */ + lld_lcdSetViewPort(x, lines > 0 ? (y+gap) : y, cx, abslines); + lld_lcdWriteStreamStart(); + gap = cx*abslines; + for(i = 0; i < gap; i++) lld_lcdWriteData(color); + lld_lcdWriteStreamStop(); + lld_lcdResetViewPort(); + } +#endif + +#endif /* HAL_USE_GDISP */ +/** @} */ diff --git a/halext/template/gdisp_lld.h b/halext/drivers/gdispS6d1121/gdisp_lld.h similarity index 98% rename from halext/template/gdisp_lld.h rename to halext/drivers/gdispS6d1121/gdisp_lld.h index 221983f4..55241715 100644 --- a/halext/template/gdisp_lld.h +++ b/halext/drivers/gdispS6d1121/gdisp_lld.h @@ -93,7 +93,6 @@ struct GDISPDriver { #if defined(GDISP_DRIVER_EXT_FIELDS) GDISP_DRIVER_EXT_FIELDS #endif - /* End of mandatory fields */ }; @@ -106,7 +105,7 @@ struct GDISPDriver { /*===========================================================================*/ #if !defined(__DOXYGEN__) - extern GDISPDriver GDISP1; + extern GDISPDriver GDISP; #endif #ifdef __cplusplus @@ -119,7 +118,7 @@ extern "C" { void gdisp_lld_setorientation(gdisp_orientation_t newOrientation); /* Some of these functions will be implemented in software by the high level driver - depending on the GDISP_HARDWARE_XXX macros defined above. + depending on the GDISP_HARDWARE_XXX macros defined in gdisp_lld_config.h. */ /* Drawing functions */ diff --git a/halext/drivers/gdispS6d1121/gdisp_lld.mk b/halext/drivers/gdispS6d1121/gdisp_lld.mk new file mode 100644 index 00000000..632655ea --- /dev/null +++ b/halext/drivers/gdispS6d1121/gdisp_lld.mk @@ -0,0 +1,5 @@ +# List the required driver. +HALSRC += ${CHIBIOS}/os/halext/drivers/gdispS6d1121/gdisp_lld.c + +# Required include directories +HALINC += ${CHIBIOS}/os/halext/drivers/gdispS6d1121 diff --git a/halext/drivers/gdispS6d1121/gdisp_lld_config.h b/halext/drivers/gdispS6d1121/gdisp_lld_config.h new file mode 100644 index 00000000..be9f81d8 --- /dev/null +++ b/halext/drivers/gdispS6d1121/gdisp_lld_config.h @@ -0,0 +1,224 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + --- + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes ChibiOS/RT, without being obliged to provide + the source code for any proprietary components. See the file exception.txt + for full details of how and when the exception can be applied. +*/ +/* + Concepts and parts of this file have been contributed by: + Joel Bodenmann aka Tectu -> Maintainer + Andrew Hannam aka inmarket -> framework + Badger -> console implementation and FSMC + Abhishek -> font rendering + Ben William -> fastMath and lcdDrawEllipse() + Dongxu Li aka dxli -> lcdDrawEllipse() filled option +*/ + +/** + * @file gdispS6d1121/gdisp_lld_config.h + * @brief GDISP Graphic Driver subsystem low level driver header for the S6d1121 display. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if HAL_USE_GDISP || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name GDISP hardware accelerated support + * @{ + */ + /** + * @brief Hardware supports changing the orientation. + * @details If set to @p FALSE a software stubb is provided. + */ + #define GDISP_HARDWARE_ORIENTATION TRUE + + /** + * @brief Hardware supports power control. + * @details If set to @p FALSE a software stubb is provided. + */ + #define GDISP_HARDWARE_POWERCONTROL FALSE + + /** + * @brief Hardware accelerated line drawing. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_LINES FALSE + + /** + * @brief Hardware accelerated box drawing. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_BOX FALSE + + /** + * @brief Hardware accelerated screen clears. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_CLEARS TRUE + + /** + * @brief Hardware accelerated rectangular fills. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_FILLS TRUE + + /** + * @brief Hardware accelerated fills from an image. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_BITFILLS TRUE + + /** + * @brief Hardware accelerated circles. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_CIRCLES FALSE + + /** + * @brief Hardware accelerated filled circles. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_CIRCLEFILLS FALSE + + /** + * @brief Hardware accelerated ellipses. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_ELLIPSES FALSE + + /** + * @brief Hardware accelerated filled ellipses. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_ELLIPSEFILLS FALSE + + /** + * @brief Hardware accelerated text drawing. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_TEXT FALSE + + /** + * @brief Hardware accelerated text drawing with a filled background. + * @details If set to @p FALSE software emulation is used. + */ + #define GDISP_HARDWARE_TEXTFILLS FALSE + + /** + * @brief Hardware accelerated scrolling. + * @details If set to @p FALSE there is no support for scrolling. + */ + #define GDISP_HARDWARE_SCROLL FALSE + + /** + * @brief Reading back of pixel values. + * @details If set to @p FALSE there is no support for pixel read-back. + */ + #define GDISP_HARDWARE_PIXELREAD FALSE +/** @} */ + +/** + * @name GDISP software algorithm choices + * @{ + */ + /** + * @brief For filled text drawing, use a background fill and then draw + * the text instead of using a blit or direct pixel drawing. + * @details If set to @p TRUE background fill and then text draw is used. + * @note This is ignored if hardware accelerated text is supported. + */ + #define GDISP_SOFTWARE_TEXTFILLDRAW FALSE + /** + * @brief For filled text drawing, when using a bitmap blit + * use a column by column buffer rather than a full character + * buffer to save memory at a small performance cost. + * @details If set to @p TRUE background fill one character column at a time. + * @note This is ignored if software text using blit is not being used. + */ + #define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE +/** @} */ + +/** + * @name GDISP pixel format choices + * @{ + */ + /** + * @brief The native pixel format for this device + * @note One of the following should be defined: + * GDISP_PIXELFORMAT_RGB565 + * GDISP_PIXELFORMAT_RGB888 + * GDISP_PIXELFORMAT_RGB444 + * GDISP_PIXELFORMAT_RGB332 + * GDISP_PIXELFORMAT_RGB666 + * GDISP_PIXELFORMAT_CUSTOM + * @note If you define GDISP_PIXELFORMAT_CUSTOM you need to also define + * color_t, RGB2COLOR(r,g,b), HTML2COLOR(h), + * RED_OF(c), GREEN_OF(c), BLUE_OF(c), + * COLOR(c) and MASKCOLOR. + */ + #define GDISP_PIXELFORMAT_RGB565 + + /** + * @brief Do pixels require packing for a blit + * @note Is only valid for a pixel format that doesn't fill it's datatype. ie formats: + * GDISP_PIXELFORMAT_RGB888 + * GDISP_PIXELFORMAT_RGB444 + * GDISP_PIXELFORMAT_RGB666 + * GDISP_PIXELFORMAT_CUSTOM + * @note If you use GDISP_PIXELFORMAT_CUSTOM and packed bit fills + * you need to also define @P gdispPackPixels(buf,cx,x,y,c) + * @note If you are using GDISP_HARDWARE_BITFILLS = FALSE then the pixel + * format must not be a packed format as the software blit does + * not support packed pixels + * @note Very few cases should actually require packed pixels as the low + * level driver can also pack on the fly as it is sending it + * to the graphics device. + */ + #define GDISP_PACKED_PIXELS FALSE + + /** + * @brief Do lines of pixels require packing for a blit + * @note Ignored if GDISP_PACKED_PIXELS is FALSE + */ + #define GDISP_PACKED_LINES FALSE + + /** + * @brief Do lines of pixels require packing for a blit + * @note Ignored if GDISP_PACKED_PIXELS is FALSE + */ + #define GDISP_PACKED_LINES FALSE +/** @} */ + +#endif /* HAL_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ +/** @} */ diff --git a/halext/drivers/gdispS6d1121/readme.txt b/halext/drivers/gdispS6d1121/readme.txt new file mode 100644 index 00000000..fc24d4a2 --- /dev/null +++ b/halext/drivers/gdispS6d1121/readme.txt @@ -0,0 +1,16 @@ +To use this driver: + +1. Add in your halconf.h: + a) #define HAL_USE_GDISP TRUE + b) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD + c) One (only) of: + #define LCD_USE_GPIO + #define LCD_USE_SPI + #define LCD_USE_FSMC + d) All of the following (with appropriate values): + #define SCREEN_WIDTH 320 + #define SCREEN_HEIGHT 240 + +2. To your makefile add the following lines: + include $(CHIBIOS)/os/halext/halext.mk + include $(CHIBIOS)/os/halext/drivers/gdispS6d1121/gdisp_lld.mk diff --git a/halext/drivers/gdispS6d1121/s6d1121_lld.c.h b/halext/drivers/gdispS6d1121/s6d1121_lld.c.h new file mode 100644 index 00000000..8e4fdd07 --- /dev/null +++ b/halext/drivers/gdispS6d1121/s6d1121_lld.c.h @@ -0,0 +1,224 @@ +#ifndef S6D1121_H +#define S6D1121_H + +// I/O assignments +#define LCD_BL_GPIO GPIOB +#define LCD_BL_PIN 8 + +#define LCD_CS_GPIO GPIOD +#define LCD_CS_PIN 7 + +#define LCD_RS_GPIO GPIOD +#define LCD_RS_PIN 11 + +#define LCD_RST_GPIO GPIOD +#define LCD_RST_PIN 10 + +#define LCD_RD_GPIO GPIOD +#define LCD_RD_PIN 9 + +#define LCD_WR_GPIO GPIOD +#define LCD_WR_PIN 8 + +#define LCD_D0_GPIO GPIOD +#define LCD_D4_GPIO GPIOE + +/* all interfaces use RST via GPIO */ +/* TODO: option to disable RST; assumes RST is tied high */ +#define LCD_RST_LOW palClearPad(LCD_RST_GPIO, LCD_RST_PIN) +#define LCD_RST_HIGH palSetPad(LCD_RST_GPIO, LCD_RST_PIN) + +#define s6d1121_delay(n) halPolledDelay(MS2RTT(n)); + +#if defined(LCD_USE_GPIO) + + #define LCD_CS_LOW palClearPad(LCD_CS_GPIO, LCD_CS_PIN) + #define LCD_CS_HIGH palSetPad(LCD_CS_GPIO, LCD_CS_PIN) + + #define LCD_RS_LOW palClearPad(LCD_RS_GPIO, LCD_RS_PIN) + #define LCD_RS_HIGH palSetPad(LCD_RS_GPIO, LCD_RS_PIN) + + #define LCD_RD_LOW palClearPad(LCD_RD_GPIO, LCD_RD_PIN) + #define LCD_RD_HIGH palSetPad(LCD_RD_GPIO, LCD_RD_PIN) + + #define LCD_WR_LOW palClearPad(LCD_WR_GPIO, LCD_WR_PIN) + #define LCD_WR_HIGH palSetPad(LCD_WR_GPIO, LCD_WR_PIN) + + #define LCD_BL_LOW palClearPad(LCD_BL_GPIO, LCD_BL_PIN) + #define LCD_BL_HIGH palSetPad(LCD_BL_GPIO, LCD_BL_PIN) + + + static inline void lld_lcddelay(void) { asm volatile ("nop"); asm volatile ("nop"); } + static inline void lld_lcdwrite(uint16_t db) { + LCD_D4_GPIO->BSRR.W=((~db&0xFFF0)<<16)|(db&0xFFF0); + LCD_D0_GPIO->BSRR.W=((~db&0x000F)<<16)|(db&0x000F); + LCD_WR_LOW; + lld_lcddelay(); + LCD_WR_HIGH; + } + static __inline uint16_t lld_lcdReadData(void) { + uint16_t value=0; + + LCD_RS_HIGH; LCD_WR_HIGH; LCD_RD_LOW; + #ifndef STM32F4XX + // change pin mode to digital input + LCD_DATA_PORT->CRH = 0x47444444; + LCD_DATA_PORT->CRL = 0x47444444; + #endif + #ifndef STM32F4XX + // change pin mode back to digital output + LCD_DATA_PORT->CRH = 0x33333333; + LCD_DATA_PORT->CRL = 0x33333333; + #endif + LCD_RD_HIGH; + return value; + } + static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { + uint16_t value; + + LCD_CS_LOW; LCD_RS_LOW; + lld_lcdwrite(lcdReg); + LCD_RS_HIGH; + lcdRAM = lld_lcdReadData(); + LCD_CS_HIGH; + return lcdRAM; + } + static void lld_lcdWriteIndex(uint16_t lcdReg) { + LCD_RS_LOW; + lld_lcdwrite(lcdReg); + LCD_RS_HIGH; + } + static void lld_lcdWriteData(uint16_t lcdData) { + lld_lcdwrite(lcdData); + } + static void lld_lcdWriteReg(uint16_t lcdReg, uint16_t lcdRegValue) { + LCD_CS_LOW; + lld_lcdWriteIndex(lcdReg); + lld_lcdWriteData(lcdRegValue); + LCD_CS_HIGH; + } + static __inline void lld_lcdWriteStreamStart(void) { + LCD_CS_LOW; + lld_lcdWriteIndex(0x0022); + } + static __inline void lld_lcdWriteStreamStop(void) { + LCD_CS_HIGH; + } + static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { + uint16_t i; + + for(i = 0; i < size; i++) { lld_lcdwrite(buffer[i]); } + } + static __inline void lld_lcdReadStreamStart(void) { /* TODO */ } + static __inline void lld_lcdReadStreamStop(void) { /* TODO */ } + static __inline void lld_lcdReadStream(uint16_t *UNUSED(buffer), size_t UNUSED(size)) { /* TODO */ } + +#elif defined(LCD_USE_FSMC) + #define LCD_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */ + #define LCD_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */ + + static __inline void lld_lcdWriteIndex(uint16_t index) { LCD_REG = index; } + static __inline void lld_lcdWriteData(uint16_t data) { LCD_RAM = data; } + static __inline void lld_lcdWriteReg(uint16_t lcdReg,uint16_t lcdRegValue) { + LCD_REG = lcdReg; + LCD_RAM = lcdRegValue; + } + static __inline uint16_t lld_lcdReadData(void) { return (LCD_RAM); } + static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { + LCD_REG = lcdReg; + return LCD_RAM; + } + static __inline void lld_lcdWriteStreamStart(void) { LCD_REG = 0x0022; } + static __inline void lld_lcdWriteStreamStop(void) {} + static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { + uint16_t i; + for(i = 0; i < size; i++) LCD_RAM = buffer[i]; + } + static __inline void lld_lcdReadStreamStart(void) { LCD_REG = 0x0022; } + static __inline void lld_lcdReadStreamStop(void) {} + static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { + uint16_t i; + volatile uint16_t dummy; + + /* throw away first value read */ + dummy = LCD_RAM; + for(i = 0; i < size; i++) buffer[i] = LCD_RAM; + } + +#elif defined(LCD_USE_SPI) + #error "gdispS6d1121: LCD_USE_SPI not implemented yet" + +#else + #error "gdispS6d1121: No known LCD_USE_XXX has been defined" +#endif + +static void lld_lcdSetCursor(coord_t x, coord_t y) { + /* R20h - 8 bit + * R21h - 9 bit + */ + switch(GDISP.Orientation) { + case portraitInv: + lld_lcdWriteReg(0x0020, (SCREEN_WIDTH-1-x) & 0x00FF); + lld_lcdWriteReg(0x0021, (SCREEN_HEIGHT-1-y) & 0x01FF); + break; + case portrait: + lld_lcdWriteReg(0x0020, x & 0x00FF); + lld_lcdWriteReg(0x0021, y & 0x01FF); + break; + case landscape: + lld_lcdWriteReg(0x0020, y & 0x00FF); + lld_lcdWriteReg(0x0021, x & 0x01FF); + break; + case landscapeInv: + lld_lcdWriteReg(0x0020, (SCREEN_WIDTH - y - 1) & 0x00FF); + lld_lcdWriteReg(0x0021, (SCREEN_HEIGHT - x - 1) & 0x01FF); + break; + } +} + +static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) { + /* HSA / HEA are 8 bit + * VSA / VEA are 9 bit + * use masks 0x00FF and 0x01FF to enforce this + */ + + switch(GDISP.Orientation) { + case portrait: + lld_lcdWriteReg(0x46, (((x+cx-1) << 8) & 0xFF00 ) | (x & 0x00FF)); + lld_lcdWriteReg(0x48, y & 0x01FF); + lld_lcdWriteReg(0x47, (y+cy-1) & 0x01FF); + break; + case landscape: + lld_lcdWriteReg(0x46, (((x+cx-1) << 8) & 0xFF00) | ((y+cy) & 0x00FF)); + lld_lcdWriteReg(0x48, x & 0x01FF); + lld_lcdWriteReg(0x47, (x+cx-1) & 0x01FF); + break; + case portraitInv: + lld_lcdWriteReg(0x46, (((SCREEN_WIDTH-x-1) & 0x00FF) << 8) | ((SCREEN_WIDTH - (x+cx)) & 0x00FF)); + lld_lcdWriteReg(0x48, (SCREEN_HEIGHT-(y+cy)) & 0x01FF); + lld_lcdWriteReg(0x47, (SCREEN_HEIGHT-y-1) & 0x01FF); + break; + case landscapeInv: + lld_lcdWriteReg(0x46, (((SCREEN_WIDTH - y - 1) & 0x00FF) << 8) | ((SCREEN_WIDTH - (y+cy)) & 0x00FF)); + lld_lcdWriteReg(0x48, (SCREEN_HEIGHT - (x+cx)) & 0x01FF); + lld_lcdWriteReg(0x47, (SCREEN_HEIGHT - x - 1) & 0x01FF); + break; + } + + lld_lcdSetCursor(x, y); +} + +static void lld_lcdResetViewPort(void) { + switch(GDISP.Orientation) { + case portrait: + case portraitInv: + lld_lcdSetViewPort(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + break; + case landscape: + case landscapeInv: + lld_lcdSetViewPort(0, 0, SCREEN_HEIGHT, SCREEN_WIDTH); + break; + } +} + +#endif /* S6D1121_H */ diff --git a/halext/drivers/gdispSsd1289/gdisp_lld.c b/halext/drivers/gdispSsd1289/gdisp_lld.c index c2f460b1..fb32418b 100644 --- a/halext/drivers/gdispSsd1289/gdisp_lld.c +++ b/halext/drivers/gdispSsd1289/gdisp_lld.c @@ -45,7 +45,7 @@ #include "ch.h" #include "hal.h" #include "gdisp.h" -#include "ssd1289_lld.h" +#include "gdisp_fonts.h" #if HAL_USE_GDISP || defined(__DOXYGEN__) @@ -67,7 +67,7 @@ /*===========================================================================*/ #if !defined(__DOXYGEN__) - GDISPDriver GDISP1; + GDISPDriver GDISP; #endif /*===========================================================================*/ @@ -78,233 +78,7 @@ /* Driver local functions. */ /*===========================================================================*/ -#ifdef LCD_USE_GPIO - static __inline void lld_lcdWriteIndex(uint16_t index) { - Clr_RS; - Set_RD; - - lld_lcdWriteGPIO(index); - - Clr_WR; - Set_WR; - } - - static __inline void lld_lcdWriteData(uint16_t data) { - Set_RS; - - lld_lcdWriteGPIO(data); - - Clr_WR; - Set_WR; - } - - static __inline void lld_lcdWriteReg(uint16_t lcdReg,uint16_t lcdRegValue) { - Clr_CS; - - lld_lcdWriteIndex(lcdReg); - lld_lcdWriteData(lcdRegValue); - - Set_CS; - } - - static __inline uint16_t lld_lcdReadData(void) { - uint16_t value; - - Set_RS; - Set_WR; - Clr_RD; - - value = lld_lcdReadGPIO(); - - Set_RD; - - return value; - } - - static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { - uint16_t lcdRAM; - - Clr_CS; - lld_lcdWriteIndex(lcdReg); - lcdRAM = lld_lcdReadData(); - - Set_CS; - - return lcdRAM; - } - - static __inline void lld_lcdWriteStreamStart(void) { - Clr_CS; - - lld_lcdWriteIndex(0x0022); - } - - static __inline void lld_lcdWriteStreamStop(void) { - Set_CS; - } - - static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { - uint16_t i; - - Set_RS; - - for(i = 0; i < size; i++) { - lld_lcdWriteGPIO(buffer[i]); - Clr_WR; - Set_WR; - } - } - - static __inline void lld_lcdReadStreamStart(void) { - Clr_CS - - lld_lcdWriteIndex(0x0022); - } - - static __inline void lld_lcdReadStreamStop(void) { - Set_CS; - } - - static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { - uint16_t i; - volatile uint16_t dummy; - - dummy = lld_lcdReadData(); - for(i = 0; i < size; i++) - buffer[i] = lld_lcdReadData(); - } -#endif // LCD_USE_GPIO - -#ifdef LCD_USE_SPI - /* TODO */ -#endif // LCD_USE_SPI - -#ifdef LCD_USE_FSMC - #define LCD_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */ - #define LCD_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */ - - static __inline void lld_lcdWriteIndex(uint16_t index) { - LCD_REG = index; - } - - static __inline void lld_lcdWriteData(uint16_t data) { - LCD_RAM = data; - } - - static __inline void lld_lcdWriteReg(uint16_t lcdReg,uint16_t lcdRegValue) { - LCD_REG = lcdReg; - LCD_RAM = lcdRegValue; - } - - static __inline uint16_t lld_lcdReadData(void) { - return (LCD_RAM); - } - - static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { - LCD_REG = lcdReg; - volatile uint16_t dummy = LCD_RAM; - return (LCD_RAM); - } - - static __inline void lld_lcdWriteStreamStart(void) { - LCD_REG = 0x0022; - } - - static __inline void lld_lcdWriteStreamStop(void) { - - } - - static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { - uint16_t i; - for(i = 0; i < size; i++) - LCD_RAM = buffer[i]; - } - - static __inline void lld_lcdReadStreamStart(void) { - LCD_REG = 0x0022; - } - - static __inline void lld_lcdReadStreamStop(void) { - - } - - static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { - uint16_t i; - /* throw away first value read */ - volatile uint16_t dummy = LCD_RAM; - - for(i = 0; i < size; i++) { - buffer[i] = LCD_RAM; - } - } -#endif // LCD_USE_FSMC - -static __inline void lld_lcdDelay(uint16_t us) { - chThdSleepMicroseconds(us); -} - -static void lld_lcdSetCursor(uint16_t x, uint16_t y) { - /* Reg 0x004E is an 8 bit value - * Reg 0x004F is 9 bit - * Use a bit mask to make sure they are not set too high - */ - switch(GDISP1.Orientation) { - case portraitInv: - lld_lcdWriteReg(0x004e, (SCREEN_WIDTH-1-x) & 0x00FF); - lld_lcdWriteReg(0x004f, (SCREEN_HEIGHT-1-y) & 0x01FF); - break; - case portrait: - lld_lcdWriteReg(0x004e, x & 0x00FF); - lld_lcdWriteReg(0x004f, y & 0x01FF); - break; - case landscape: - lld_lcdWriteReg(0x004e, y & 0x00FF); - lld_lcdWriteReg(0x004f, x & 0x01FF); - break; - case landscapeInv: - lld_lcdWriteReg(0x004e, (SCREEN_WIDTH - y - 1) & 0x00FF); - lld_lcdWriteReg(0x004f, (SCREEN_HEIGHT - x - 1) & 0x01FF); - break; - } -} - -void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) { - lld_lcdSetCursor(x, y); - - /* Reg 0x44 - Horizontal RAM address position - * Upper Byte - HEA - * Lower Byte - HSA - * 0 <= HSA <= HEA <= 0xEF - * Reg 0x45,0x46 - Vertical RAM address position - * Lower 9 bits gives 0-511 range in each value - * 0 <= Reg(0x45) <= Reg(0x46) <= 0x13F - */ - - switch(GDISP1.Orientation) { - case portrait: - lld_lcdWriteReg(0x44, (((x+cx-1) << 8) & 0xFF00 ) | (x & 0x00FF)); - lld_lcdWriteReg(0x45, y & 0x01FF); - lld_lcdWriteReg(0x46, (y+cy-1) & 0x01FF); - break; - case landscape: - lld_lcdWriteReg(0x44, (((x+cx-1) << 8) & 0xFF00) | ((y+cy) & 0x00FF)); - lld_lcdWriteReg(0x45, x & 0x01FF); - lld_lcdWriteReg(0x46, (x+cx-1) & 0x01FF); - break; - case portraitInv: - lld_lcdWriteReg(0x44, (((SCREEN_WIDTH-x-1) & 0x00FF) << 8) | ((SCREEN_WIDTH - (x+cx)) & 0x00FF)); - lld_lcdWriteReg(0x45, (SCREEN_HEIGHT-(y+cy)) & 0x01FF); - lld_lcdWriteReg(0x46, (SCREEN_HEIGHT-y-1) & 0x01FF); - break; - case landscapeInv: - lld_lcdWriteReg(0x44, (((SCREEN_WIDTH - y - 1) & 0x00FF) << 8) | ((SCREEN_WIDTH - (y+cy)) & 0x00FF)); - lld_lcdWriteReg(0x45, (SCREEN_HEIGHT - (x+cx)) & 0x01FF); - lld_lcdWriteReg(0x46, (SCREEN_HEIGHT - x - 1) & 0x01FF); - break; - } - - lld_lcdSetCursor(x, y); -} +#include "ssd1289_lld.c.h" /*===========================================================================*/ /* Driver interrupt handlers. */ @@ -314,6 +88,9 @@ void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) { /* Driver exported functions. */ /*===========================================================================*/ +/* Include the software emulation routines */ +#include "gdisp_lld_inc_emulation.c.h" + /* ---- Required Routines ---- */ /* The following 2 routines are required. @@ -392,10 +169,10 @@ void gdisp_lld_init(void) { lld_lcdWriteReg(0x004e,0x0000); lld_lcdDelay(5); /* Initialise the GDISP structure */ - GDISP1.Width = SCREEN_WIDTH; - GDISP1.Height = SCREEN_HEIGHT; - GDISP1.Orientation = portrait; - GDISP1.Powermode = powerOn; + GDISP.Width = SCREEN_WIDTH; + GDISP.Height = SCREEN_HEIGHT; + GDISP.Orientation = portrait; + GDISP.Powermode = powerOn; } /** @@ -409,7 +186,7 @@ void gdisp_lld_init(void) { */ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { #if GDISP_NEED_VALIDATION - if (x >= GDISP1.Width || y >= GDISP1.Height) return; + if (x >= GDISP.Width || y >= GDISP.Height) return; #endif lld_lcdSetCursor(x, y); lld_lcdWriteReg(0x0022, color); @@ -443,7 +220,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { * @notapi */ void gdisp_lld_setpowermode(gdisp_powermode_t powerMode) { - if (GDISP1.Powermode == powerMode) + if (GDISP.Powermode == powerMode) return; switch(powerMode) { @@ -455,7 +232,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { break; case powerOn: lld_lcdWriteReg(0x0010, 0x0000); // leave sleep mode - if (GDISP1.Powermode != powerSleep) + if (GDISP.Powermode != powerSleep) gdisp_lld_init(); break; case powerSleep: @@ -465,7 +242,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { return; } - GDISP1.Powermode = powerMode; + GDISP.Powermode = powerMode; } #endif @@ -479,7 +256,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { * @notapi */ void gdisp_lld_setorientation(gdisp_orientation_t newOrientation) { - if (GDISP1.Orientation == newOrientation) + if (GDISP.Orientation == newOrientation) return; switch(newOrientation) { @@ -487,34 +264,34 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { lld_lcdWriteReg(0x0001, 0x2B3F); /* ID = 11 AM = 0 */ lld_lcdWriteReg(0x0011, 0x6070); - GDISP1.Height = SCREEN_HEIGHT; - GDISP1.Width = SCREEN_WIDTH; + GDISP.Height = SCREEN_HEIGHT; + GDISP.Width = SCREEN_WIDTH; break; case landscape: lld_lcdWriteReg(0x0001, 0x293F); /* ID = 11 AM = 1 */ lld_lcdWriteReg(0x0011, 0x6078); - GDISP1.Height = SCREEN_WIDTH; - GDISP1.Width = SCREEN_HEIGHT; + GDISP.Height = SCREEN_WIDTH; + GDISP.Width = SCREEN_HEIGHT; break; case portraitInv: lld_lcdWriteReg(0x0001, 0x2B3F); /* ID = 01 AM = 0 */ lld_lcdWriteReg(0x0011, 0x6040); - GDISP1.Height = SCREEN_HEIGHT; - GDISP1.Width = SCREEN_WIDTH; + GDISP.Height = SCREEN_HEIGHT; + GDISP.Width = SCREEN_WIDTH; break; case landscapeInv: lld_lcdWriteReg(0x0001, 0x293F); /* ID = 01 AM = 1 */ lld_lcdWriteReg(0x0011, 0x6048); - GDISP1.Height = SCREEN_WIDTH; - GDISP1.Width = SCREEN_HEIGHT; + GDISP.Height = SCREEN_WIDTH; + GDISP.Width = SCREEN_HEIGHT; break; default: return; } - GDISP1.Orientation = newOrientation; + GDISP.Orientation = newOrientation; } #endif @@ -528,7 +305,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { * @notapi */ void gdisp_lld_clear(color_t color) { - unsigned i = 0; + unsigned i; lld_lcdSetCursor(0, 0); lld_lcdWriteStreamStart(); @@ -586,9 +363,9 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { */ void gdisp_lld_fillarea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP1.Width || y >= GDISP1.Height) return; - if (x+cx > GDISP1.Width) cx = GDISP1.Width - x; - if (y+cy > GDISP1.Height) cy = GDISP1.Height - y; + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) cx = GDISP.Width - x; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; #endif unsigned i, area; @@ -599,6 +376,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { for(i = 0; i < area; i++) lld_lcdWriteData(color); lld_lcdWriteStreamStop(); + lld_lcdResetViewPort(); } #endif @@ -617,9 +395,9 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { unsigned i, area; #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP1.Width || y >= GDISP1.Height) return; - if (x+cx > GDISP1.Width) return; - if (y+cy > GDISP1.Height) cy = GDISP1.Height - y; + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) return; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; #endif area = cx*cy; @@ -628,6 +406,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { for(i = 0; i < area; i++) lld_lcdWriteData(*buffer++); lld_lcdWriteStreamStop(); + lld_lcdResetViewPort(); } #endif @@ -751,7 +530,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { color_t color; #if GDISP_NEED_VALIDATION - if (x >= GDISP1.Width || y >= GDISP1.Height) return 0; + if (x >= GDISP.Width || y >= GDISP.Height) return 0; #endif lld_lcdSetCursor(x, y); @@ -788,9 +567,9 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { abslines = lines < 0 ? -lines : lines; #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP1.Width || y >= GDISP1.Height) return; - if (x+cx > GDISP1.Width) cx = GDISP1.Width - x; - if (y+cy > GDISP1.Height) cy = GDISP1.Height - y; + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) cx = GDISP.Width - x; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; #endif if (!abslines) return; @@ -827,6 +606,7 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { gap = cx*abslines; for(i = 0; i < gap; i++) lld_lcdWriteData(color); lld_lcdWriteStreamStop(); + lld_lcdResetViewPort(); } #endif diff --git a/halext/drivers/gdispSsd1289/gdisp_lld.h b/halext/drivers/gdispSsd1289/gdisp_lld.h index ba7eb333..55241715 100644 --- a/halext/drivers/gdispSsd1289/gdisp_lld.h +++ b/halext/drivers/gdispSsd1289/gdisp_lld.h @@ -35,8 +35,8 @@ */ /** - * @file gdispSsd1289/gdisp_lld.h - * @brief GDISP Graphic Driver subsystem low level driver header for the Ssd1289 display. + * @file templates/gdisp_lld.h + * @brief GDISP Graphic Driver subsystem low level driver header template. * * @addtogroup GDISP * @{ @@ -93,7 +93,6 @@ struct GDISPDriver { #if defined(GDISP_DRIVER_EXT_FIELDS) GDISP_DRIVER_EXT_FIELDS #endif - /* End of mandatory fields */ }; @@ -106,7 +105,7 @@ struct GDISPDriver { /*===========================================================================*/ #if !defined(__DOXYGEN__) - extern GDISPDriver GDISP1; + extern GDISPDriver GDISP; #endif #ifdef __cplusplus @@ -119,7 +118,7 @@ extern "C" { void gdisp_lld_setorientation(gdisp_orientation_t newOrientation); /* Some of these functions will be implemented in software by the high level driver - depending on the GDISP_HARDWARE_XXX macros defined above. + depending on the GDISP_HARDWARE_XXX macros defined in gdisp_lld_config.h. */ /* Drawing functions */ diff --git a/halext/drivers/gdispSsd1289/readme.txt b/halext/drivers/gdispSsd1289/readme.txt index 042c5d2a..17d22223 100644 --- a/halext/drivers/gdispSsd1289/readme.txt +++ b/halext/drivers/gdispSsd1289/readme.txt @@ -1,8 +1,16 @@ -To use this driver you need to define: - One of: - LCD_USE_GPIO - LCD_USE_SPI - Not implemented yet - LCD_USE_FSMC - Need to define all of: - SCREEN_WIDTH - SCREEN_HEIGHT +To use this driver: + +1. Add in your halconf.h: + a) #define HAL_USE_GDISP TRUE + b) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD + c) One (only) of: + #define LCD_USE_GPIO + #define LCD_USE_SPI + #define LCD_USE_FSMC + d) All of the following (with appropriate values): + #define SCREEN_WIDTH 320 + #define SCREEN_HEIGHT 240 + +2. To your makefile add the following lines: + include $(CHIBIOS)/os/halext/halext.mk + include $(CHIBIOS)/os/halext/drivers/gdispSsd1289/gdisp_lld.mk diff --git a/halext/drivers/gdispSsd1289/ssd1289_lld.c.h b/halext/drivers/gdispSsd1289/ssd1289_lld.c.h new file mode 100644 index 00000000..e705b4a8 --- /dev/null +++ b/halext/drivers/gdispSsd1289/ssd1289_lld.c.h @@ -0,0 +1,302 @@ +#ifndef SSD1289_H +#define SSD1289_H + +#if defined(LCD_USE_GPIO) + #define Set_CS palSetPad(LCD_CMD_PORT, LCD_CS); + #define Clr_CS palClearPad(LCD_CMD_PORT, LCD_CS); + #define Set_RS palSetPad(LCD_CMD_PORT, LCD_RS); + #define Clr_RS palClearPad(LCD_CMD_PORT, LCD_RS); + #define Set_WR palSetPad(LCD_CMD_PORT, LCD_WR); + #define Clr_WR palClearPad(LCD_CMD_PORT, LCD_WR); + #define Set_RD palSetPad(LCD_CMD_PORT, LCD_RD); + #define Clr_RD palClearPad(LCD_CMD_PORT, LCD_RD); + + static __inline void lld_lcdWriteIndex(uint16_t index) { + Clr_RS; Set_RD; + lld_lcdWriteGPIO(index); + Clr_WR; Set_WR; + } + static __inline void lld_lcdWriteData(uint16_t data) { + Set_RS; + lld_lcdWriteGPIO(data); + Clr_WR; Set_WR; + } + static __inline void lld_lcdWriteReg(uint16_t lcdReg,uint16_t lcdRegValue) { + Clr_CS; + lld_lcdWriteIndex(lcdReg); + lld_lcdWriteData(lcdRegValue); + Set_CS; + } + static __inline uint16_t lld_lcdReadData(void) { + uint16_t value; + + Set_RS; Set_WR; Clr_RD; + value = lld_lcdReadGPIO(); + Set_RD; + return value; + } + static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { + uint16_t value; + + Clr_CS; + lld_lcdWriteIndex(lcdReg); + value = lld_lcdReadData(); + Set_CS; + return value; + } + + static __inline void lld_lcdWriteStreamStart(void) { + Clr_CS; + lld_lcdWriteIndex(0x0022); + } + + static __inline void lld_lcdWriteStreamStop(void) { + Set_CS; + } + + static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { + uint16_t i; + + Set_RS; + for(i = 0; i < size; i++) { lld_lcdWriteGPIO(buffer[i]); Clr_WR; Set_WR; } + } + + static __inline void lld_lcdReadStreamStart(void) { + Clr_CS + lld_lcdWriteIndex(0x0022); + } + + static __inline void lld_lcdReadStreamStop(void) { + Set_CS; + } + + static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { + uint16_t i; + volatile uint16_t dummy; + + dummy = lld_lcdReadData(); + for(i = 0; i < size; i++) buffer[i] = lld_lcdReadData(); + } + +#elif defined(LCD_USE_FSMC) + /* LCD Registers */ + #define R0 0x00 + #define R1 0x01 + #define R2 0x02 + #define R3 0x03 + #define R4 0x04 + #define R5 0x05 + #define R6 0x06 + #define R7 0x07 + #define R8 0x08 + #define R9 0x09 + #define R10 0x0A + #define R12 0x0C + #define R13 0x0D + #define R14 0x0E + #define R15 0x0F + #define R16 0x10 + #define R17 0x11 + #define R18 0x12 + #define R19 0x13 + #define R20 0x14 + #define R21 0x15 + #define R22 0x16 + #define R23 0x17 + #define R24 0x18 + #define R25 0x19 + #define R26 0x1A + #define R27 0x1B + #define R28 0x1C + #define R29 0x1D + #define R30 0x1E + #define R31 0x1F + #define R32 0x20 + #define R33 0x21 + #define R34 0x22 + #define R36 0x24 + #define R37 0x25 + #define R40 0x28 + #define R41 0x29 + #define R43 0x2B + #define R45 0x2D + #define R48 0x30 + #define R49 0x31 + #define R50 0x32 + #define R51 0x33 + #define R52 0x34 + #define R53 0x35 + #define R54 0x36 + #define R55 0x37 + #define R56 0x38 + #define R57 0x39 + #define R59 0x3B + #define R60 0x3C + #define R61 0x3D + #define R62 0x3E + #define R63 0x3F + #define R64 0x40 + #define R65 0x41 + #define R66 0x42 + #define R67 0x43 + #define R68 0x44 + #define R69 0x45 + #define R70 0x46 + #define R71 0x47 + #define R72 0x48 + #define R73 0x49 + #define R74 0x4A + #define R75 0x4B + #define R76 0x4C + #define R77 0x4D + #define R78 0x4E + #define R79 0x4F + #define R80 0x50 + #define R81 0x51 + #define R82 0x52 + #define R83 0x53 + #define R96 0x60 + #define R97 0x61 + #define R106 0x6A + #define R118 0x76 + #define R128 0x80 + #define R129 0x81 + #define R130 0x82 + #define R131 0x83 + #define R132 0x84 + #define R133 0x85 + #define R134 0x86 + #define R135 0x87 + #define R136 0x88 + #define R137 0x89 + #define R139 0x8B + #define R140 0x8C + #define R141 0x8D + #define R143 0x8F + #define R144 0x90 + #define R145 0x91 + #define R146 0x92 + #define R147 0x93 + #define R148 0x94 + #define R149 0x95 + #define R150 0x96 + #define R151 0x97 + #define R152 0x98 + #define R153 0x99 + #define R154 0x9A + #define R157 0x9D + #define R192 0xC0 + #define R193 0xC1 + #define R229 0xE5 + + #define LCD_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */ + #define LCD_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */ + + static __inline void lld_lcdWriteIndex(uint16_t index) { LCD_REG = index; } + static __inline void lld_lcdWriteData(uint16_t data) { LCD_RAM = data; } + static __inline void lld_lcdWriteReg(uint16_t lcdReg,uint16_t lcdRegValue) { + LCD_REG = lcdReg; + LCD_RAM = lcdRegValue; + } + static __inline uint16_t lld_lcdReadData(void) { return (LCD_RAM); } + static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { + volatile uint16_t dummy; + + LCD_REG = lcdReg; + dummy = LCD_RAM; + return (LCD_RAM); + } + static __inline void lld_lcdWriteStreamStart(void) { LCD_REG = 0x0022; } + static __inline void lld_lcdWriteStreamStop(void) {} + static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { + uint16_t i; + + for(i = 0; i < size; i++) LCD_RAM = buffer[i]; + } + static __inline void lld_lcdReadStreamStart(void) { LCD_REG = 0x0022; } + static __inline void lld_lcdReadStreamStop(void) {} + static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { + uint16_t i; + volatile uint16_t dummy; + + dummy = LCD_RAM; /* throw away first value read */ + for(i = 0; i < size; i++) buffer[i] = LCD_RAM; + } + +#elif defined(LCD_USE_SPI) + #error "gdispSsd1289: LCD_USE_SPI not implemented yet" + +#else + #error "gdispSsd1289: No known LCD_USE_XXX has been defined" +#endif + +static __inline void lld_lcdDelay(uint16_t us) { + chThdSleepMicroseconds(us); +} + +static void lld_lcdSetCursor(uint16_t x, uint16_t y) { + /* Reg 0x004E is an 8 bit value + * Reg 0x004F is 9 bit + * Use a bit mask to make sure they are not set too high + */ + switch(GDISP.Orientation) { + case portraitInv: + lld_lcdWriteReg(0x004e, (SCREEN_WIDTH-1-x) & 0x00FF); + lld_lcdWriteReg(0x004f, (SCREEN_HEIGHT-1-y) & 0x01FF); + break; + case portrait: + lld_lcdWriteReg(0x004e, x & 0x00FF); + lld_lcdWriteReg(0x004f, y & 0x01FF); + break; + case landscape: + lld_lcdWriteReg(0x004e, y & 0x00FF); + lld_lcdWriteReg(0x004f, x & 0x01FF); + break; + case landscapeInv: + lld_lcdWriteReg(0x004e, (SCREEN_WIDTH - y - 1) & 0x00FF); + lld_lcdWriteReg(0x004f, (SCREEN_HEIGHT - x - 1) & 0x01FF); + break; + } +} + +static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) { + lld_lcdSetCursor(x, y); + + /* Reg 0x44 - Horizontal RAM address position + * Upper Byte - HEA + * Lower Byte - HSA + * 0 <= HSA <= HEA <= 0xEF + * Reg 0x45,0x46 - Vertical RAM address position + * Lower 9 bits gives 0-511 range in each value + * 0 <= Reg(0x45) <= Reg(0x46) <= 0x13F + */ + + switch(GDISP.Orientation) { + case portrait: + lld_lcdWriteReg(0x44, (((x+cx-1) << 8) & 0xFF00 ) | (x & 0x00FF)); + lld_lcdWriteReg(0x45, y & 0x01FF); + lld_lcdWriteReg(0x46, (y+cy-1) & 0x01FF); + break; + case landscape: + lld_lcdWriteReg(0x44, (((x+cx-1) << 8) & 0xFF00) | ((y+cy) & 0x00FF)); + lld_lcdWriteReg(0x45, x & 0x01FF); + lld_lcdWriteReg(0x46, (x+cx-1) & 0x01FF); + break; + case portraitInv: + lld_lcdWriteReg(0x44, (((SCREEN_WIDTH-x-1) & 0x00FF) << 8) | ((SCREEN_WIDTH - (x+cx)) & 0x00FF)); + lld_lcdWriteReg(0x45, (SCREEN_HEIGHT-(y+cy)) & 0x01FF); + lld_lcdWriteReg(0x46, (SCREEN_HEIGHT-y-1) & 0x01FF); + break; + case landscapeInv: + lld_lcdWriteReg(0x44, (((SCREEN_WIDTH - y - 1) & 0x00FF) << 8) | ((SCREEN_WIDTH - (y+cy)) & 0x00FF)); + lld_lcdWriteReg(0x45, (SCREEN_HEIGHT - (x+cx)) & 0x01FF); + lld_lcdWriteReg(0x46, (SCREEN_HEIGHT - x - 1) & 0x01FF); + break; + } + + lld_lcdSetCursor(x, y); +} + +static __inline void lld_lcdResetViewPort(void) {} + +#endif /* SSD1289_H */ diff --git a/halext/drivers/gdispSsd1289/ssd1289_lld.h b/halext/drivers/gdispSsd1289/ssd1289_lld.h deleted file mode 100644 index 2d05a4aa..00000000 --- a/halext/drivers/gdispSsd1289/ssd1289_lld.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef SSD1289_H -#define SSD1289_H - -#ifdef LCD_USE_GPIO - #define Set_CS palSetPad(LCD_CMD_PORT, LCD_CS); - #define Clr_CS palClearPad(LCD_CMD_PORT, LCD_CS); - #define Set_RS palSetPad(LCD_CMD_PORT, LCD_RS); - #define Clr_RS palClearPad(LCD_CMD_PORT, LCD_RS); - #define Set_WR palSetPad(LCD_CMD_PORT, LCD_WR); - #define Clr_WR palClearPad(LCD_CMD_PORT, LCD_WR); - #define Set_RD palSetPad(LCD_CMD_PORT, LCD_RD); - #define Clr_RD palClearPad(LCD_CMD_PORT, LCD_RD); -#endif - -#ifdef LCD_USE_SPI - /* TODO */ -#endif - -#ifdef LCD_USE_FSMC -/* LCD Registers */ - #define R0 0x00 - #define R1 0x01 - #define R2 0x02 - #define R3 0x03 - #define R4 0x04 - #define R5 0x05 - #define R6 0x06 - #define R7 0x07 - #define R8 0x08 - #define R9 0x09 - #define R10 0x0A - #define R12 0x0C - #define R13 0x0D - #define R14 0x0E - #define R15 0x0F - #define R16 0x10 - #define R17 0x11 - #define R18 0x12 - #define R19 0x13 - #define R20 0x14 - #define R21 0x15 - #define R22 0x16 - #define R23 0x17 - #define R24 0x18 - #define R25 0x19 - #define R26 0x1A - #define R27 0x1B - #define R28 0x1C - #define R29 0x1D - #define R30 0x1E - #define R31 0x1F - #define R32 0x20 - #define R33 0x21 - #define R34 0x22 - #define R36 0x24 - #define R37 0x25 - #define R40 0x28 - #define R41 0x29 - #define R43 0x2B - #define R45 0x2D - #define R48 0x30 - #define R49 0x31 - #define R50 0x32 - #define R51 0x33 - #define R52 0x34 - #define R53 0x35 - #define R54 0x36 - #define R55 0x37 - #define R56 0x38 - #define R57 0x39 - #define R59 0x3B - #define R60 0x3C - #define R61 0x3D - #define R62 0x3E - #define R63 0x3F - #define R64 0x40 - #define R65 0x41 - #define R66 0x42 - #define R67 0x43 - #define R68 0x44 - #define R69 0x45 - #define R70 0x46 - #define R71 0x47 - #define R72 0x48 - #define R73 0x49 - #define R74 0x4A - #define R75 0x4B - #define R76 0x4C - #define R77 0x4D - #define R78 0x4E - #define R79 0x4F - #define R80 0x50 - #define R81 0x51 - #define R82 0x52 - #define R83 0x53 - #define R96 0x60 - #define R97 0x61 - #define R106 0x6A - #define R118 0x76 - #define R128 0x80 - #define R129 0x81 - #define R130 0x82 - #define R131 0x83 - #define R132 0x84 - #define R133 0x85 - #define R134 0x86 - #define R135 0x87 - #define R136 0x88 - #define R137 0x89 - #define R139 0x8B - #define R140 0x8C - #define R141 0x8D - #define R143 0x8F - #define R144 0x90 - #define R145 0x91 - #define R146 0x92 - #define R147 0x93 - #define R148 0x94 - #define R149 0x95 - #define R150 0x96 - #define R151 0x97 - #define R152 0x98 - #define R153 0x99 - #define R154 0x9A - #define R157 0x9D - #define R192 0xC0 - #define R193 0xC1 - #define R229 0xE5 -#endif - -#endif diff --git a/halext/include/gdisp.h b/halext/include/gdisp.h index 036f2fd4..12f9995c 100644 --- a/halext/include/gdisp.h +++ b/halext/include/gdisp.h @@ -256,7 +256,10 @@ #define gdispPackPixels(buf,cx,x,y,c) { ((color_t *)(buf))[(y)*(cx)+(x)] = (c); } #elif !GDISP_HARDWARE_BITFILLS #error "GDISP: packed pixel formats are only supported for hardware accelerated drivers." -#elif !defined(GDISP_PIXELFORMAT_RGB888) && !defined(GDISP_PIXELFORMAT_RGB444) && !defined(GDISP_PIXELFORMAT_RGB666) && !defined(GDISP_PIXELFORMAT_CUSTOM) +#elif !defined(GDISP_PIXELFORMAT_RGB888) \ + && !defined(GDISP_PIXELFORMAT_RGB444) \ + && !defined(GDISP_PIXELFORMAT_RGB666) \ + && !defined(GDISP_PIXELFORMAT_CUSTOM) #error "GDISP: A packed pixel format has been specified for an unsupported pixel format." #endif @@ -382,20 +385,20 @@ extern "C" { #endif - /* Extra Text Functions */ - #if GDISP_NEED_TEXT +/* Extra Text Functions */ +#if GDISP_NEED_TEXT void gdispDrawString(coord_t x, coord_t y, const char *str, font_t font, color_t color); void gdispFillString(coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor); void gdispFillStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgColor, justify_t justify); coord_t gdispGetFontMetric(font_t font, fontmetric_t metric); coord_t gdispGetCharWidth(char c, font_t font); coord_t gdispGetStringWidth(const char* str, font_t font); - #endif +#endif - /* Support routine for packed pixel formats */ - #ifndef gdispPackPixels +/* Support routine for packed pixel formats */ +#ifndef gdispPackPixels void gdispPackPixels(pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color); - #endif +#endif #ifdef __cplusplus } diff --git a/halext/include/gdisp_fonts.h b/halext/include/gdisp_fonts.h new file mode 100644 index 00000000..d1cad898 --- /dev/null +++ b/halext/include/gdisp_fonts.h @@ -0,0 +1,104 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + --- + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes ChibiOS/RT, without being obliged to provide + the source code for any proprietary components. See the file exception.txt + for full details of how and when the exception can be applied. +*/ +/* + Concepts and parts of this file have been contributed by: + Joel Bodenmann aka Tectu -> Maintainer + Andrew Hannam aka inmarket -> Framework + Badger -> console implementation and FSMC + Abhishek -> font rendering + Ben William -> fastMath and lcdDrawEllipse() + Dongxu Li aka dxli -> lcdDrawEllipse() filled option +*/ + +/** + * @file gdisp_fonts.h + * @brief GDISP internal font definitions. + * @details This is not generally needed by an application. It is used + * by the low level drivers that need to understand a font. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_FONTS_H +#define _GDISP_FONTS_H + +/** + * @brief The maximum height of a font. + * @details Either 16 or 32. Defaults to 16 + * @note Setting this to 32 causes the font tables to take + * twice the internal program memory. + */ +#ifndef GDISP_MAX_FONT_HEIGHT + #define GDISP_MAX_FONT_HEIGHT 16 +#endif + +/** + * @brief The type of a font column. + * @note Set by defining @p GDISP_MAX_FNT_HEIGHT appropriately. + */ +#if GDISP_MAX_FONT_HEIGHT == 16 + typedef uint16_t fontcolumn_t; +#elif GDISP_MAX_FONT_HEIGHT == 32 + typedef uint32_t fontcolumn_t; +#else + #error "GDISP: GDISP_MAX_FONT_HEIGHT must be either 16 or 32" +#endif + +/** + * @brief Internal font structure. + * @note This structure is followed by: + * 1. An array of character widths (uint8_t) + * 2. An array of column data offsets (relative to the font structure) + * 3. Each characters array of column data (fontcolumn_t) + * Each sub-structure must be padded to a multiple of 8 bytes + * to allow the tables to work accross many different compilers. + */ +struct font { + uint8_t height; + uint8_t charPadding; + uint8_t lineSpacing; + uint8_t descenderHeight; + uint8_t minWidth; + uint8_t maxWidth; + char minChar; + char maxChar; + uint16_t offsetTableOffset; + uint16_t unused1; /* ensure next field is padded to 8 byte boundary */ + uint8_t widthTable[]; + }; + +/** + * @brief Macro's to get to the complex parts of the font structure. + */ +#define _getFontPart(f,o,t) ((t)(&((const uint8_t *)(f))[(o)])) +#define _getCharWidth(f,c) (((c) < (f)->minChar || (c) > (f)->maxChar) ? 0 : (f)->widthTable[c - (f)->minChar]) +#define _getCharOffset(f,c) (_getFontPart((f), (f)->offsetTableOffset, const uint16_t *)[c - (f)->minChar]) +#define _getCharData(f,c) _getFontPart((f), _getCharOffset((f),(c)), const fontcolumn_t *) + +#endif /* _GDISP_FONTS_H */ +/** @} */ diff --git a/halext/src/gdisp_inc_fonts.c b/halext/include/gdisp_inc_fonts.c.h similarity index 99% rename from halext/src/gdisp_inc_fonts.c rename to halext/include/gdisp_inc_fonts.c.h index 41c6a087..01869553 100644 --- a/halext/src/gdisp_inc_fonts.c +++ b/halext/include/gdisp_inc_fonts.c.h @@ -34,6 +34,8 @@ Dongxu Li aka dxli -> lcdDrawEllipse() filled option */ +#include "gdisp_fonts.h" + /* Font tables included into gdisp.c */ diff --git a/halext/src/gdisp_inc_emulation.c b/halext/include/gdisp_lld_inc_emulation.c.h similarity index 95% rename from halext/src/gdisp_inc_emulation.c rename to halext/include/gdisp_lld_inc_emulation.c.h index 783df480..623e85a5 100644 --- a/halext/src/gdisp_inc_emulation.c +++ b/halext/include/gdisp_lld_inc_emulation.c.h @@ -35,7 +35,7 @@ */ /* - Emulation routines included into gdisp.c + Emulation routines included into gdisp_lld.c */ /* @@ -57,7 +57,7 @@ #if !GDISP_HARDWARE_CLEARS void gdisp_lld_clear(color_t color) { - gdisp_lld_fillarea(0, 0, GDISP1.Width, GDISP1.Height, color); + gdisp_lld_fillarea(0, 0, GDISP.Width, GDISP.Height, color); } #endif diff --git a/halext/src/gdisp.c b/halext/src/gdisp.c index 7259db0a..e7b0bc49 100644 --- a/halext/src/gdisp.c +++ b/halext/src/gdisp.c @@ -50,6 +50,7 @@ #if GDISP_NEED_MULTITHREAD #warning "GDISP: Multithread support not complete" + #define MUTEX_INIT /* Not defined yet */ #define MUTEX_ENTER /* Not defined yet */ #define MUTEX_EXIT /* Not defined yet */ #endif @@ -67,51 +68,12 @@ # define UNUSED(x) x #endif -#if GDISP_NEED_TEXT || defined(__DOXYGEN__) - /** - * @brief The size of a font column. - * @note If you font heights > 16 you would need to redefine this - * as a uint32_t instead of a uint16_t. Fonts would then take - * twice the internal program memory. - */ - typedef uint16_t fontcolumn_t; - - /** - * @brief Internal font structure. - * @note This structure is followed by: - * An array of column data offsets (relative to the font structure) - * An array of character widths (uint8_t) - * Each characters array of column data (fontcolumn_t) - */ - struct font { - uint8_t height; - uint8_t charPadding; - uint8_t lineSpacing; - uint8_t descenderHeight; - uint8_t minWidth; - uint8_t maxWidth; - char minChar; - char maxChar; - uint16_t offsetTableOffset; - uint16_t unused1; /* ensure next field is padded to 8 byte boundary */ - uint8_t widthTable[]; - }; - - /** - * @brief Macro's to get to the complex parts of the font structure. - */ - #define _getFontPart(f,o,t) ((t)(&((const uint8_t *)(f))[(o)])) - #define _getCharWidth(f,c) (((c) < (f)->minChar || (c) > (f)->maxChar) ? 0 : (f)->widthTable[c - (f)->minChar]) - #define _getCharOffset(f,c) (_getFontPart((f), (f)->offsetTableOffset, const uint16_t *)[c - (f)->minChar]) - #define _getCharData(f,c) _getFontPart((f), _getCharOffset((f),(c)), const fontcolumn_t *) -#endif - /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ #if GDISP_NEED_TEXT || defined(__DOXYGEN__) - #include "gdisp_inc_fonts.c" + #include "gdisp_inc_fonts.c.h" #endif /*===========================================================================*/ @@ -126,9 +88,6 @@ /* Driver exported functions. */ /*===========================================================================*/ -/* Include the software emulation routines */ -#include "gdisp_inc_emulation.c" - #if GDISP_NEED_MULTITHREAD || defined(__DOXYGEN__) /** * @brief GDISP Driver initialization. @@ -138,10 +97,13 @@ * @init */ void gdispInit(GDISPDriver * UNUSED(gdisp)) { - /* No mutex required as nothing should happen until the init is complete */ + /* Initialise Mutex */ + MUTEX_INIT + + /* Initialise driver */ + MUTEX_ENTER gdisp_lld_init(); - - /* ToDo - Initialise Mutex */ + MUTEX_EXIT } #endif diff --git a/halext/template/gdisp_lld.c b/halext/templates/gdispXXXXX/gdisp_lld.c similarity index 80% rename from halext/template/gdisp_lld.c rename to halext/templates/gdispXXXXX/gdisp_lld.c index 4d715a50..acbd5c9d 100644 --- a/halext/template/gdisp_lld.c +++ b/halext/templates/gdispXXXXX/gdisp_lld.c @@ -45,6 +45,7 @@ #include "ch.h" #include "hal.h" #include "gdisp.h" +#include "gdisp_fonts.h" #if HAL_USE_GDISP || defined(__DOXYGEN__) @@ -66,7 +67,7 @@ /*===========================================================================*/ #if !defined(__DOXYGEN__) - GDISPDriver GDISP1; + GDISPDriver GDISP; #endif /*===========================================================================*/ @@ -85,6 +86,9 @@ /* Driver exported functions. */ /*===========================================================================*/ +/* Include the software emulation routines */ +#include "gdisp_lld_inc_emulation.c.h" + /* ---- Required Routines ---- */ /* The following 2 routines are required. @@ -97,14 +101,13 @@ * @notapi */ void gdisp_lld_init(void) { - /* Initialise the GDISP structure with the defaults for your display */ - GDISP1.Width = 128; - GDISP1.Height = 128; - GDISP1.Orientation = portrait; - GDISP1.Powermode = powerOff; - - /* Now initialise your display to match */ - /* Code here */ + /* Initialise your display */ + + /* Initialise the GDISP structure to match */ + GDISP.Width = SCREEN_WIDTH; + GDISP.Height = SCREEN_HEIGHT; + GDISP.Orientation = portrait; + GDISP.Powermode = powerOn; } /** @@ -118,7 +121,7 @@ void gdisp_lld_init(void) { */ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { #if GDISP_NEED_VALIDATION - if (x >= GDISP1.Width || y >= GDISP1.Height) return; + if (x >= GDISP.Width || y >= GDISP.Height) return; #endif /* Code here */ } @@ -141,38 +144,80 @@ void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color) { */ #if GDISP_HARDWARE_POWERCONTROL || defined(__DOXYGEN__) -/** - * @brief Sets the power mode for the graphic device. - * @note The power modes are powerOn, powerSleep and powerOff. - * If powerSleep is not supported it is equivelent to powerOn. - * - * @param[in] powerMode The new power mode - * - * @notapi - */ -void gdisp_lld_setpowermode(gdisp_powermode_t powerMode) { - /* Code here */ - /* if successful - GDISP1.Powermode = powerMode; - */ -} + /** + * @brief Sets the power mode for the graphic device. + * @note The power modes are powerOn, powerSleep and powerOff. + * If powerSleep is not supported it is equivalent to powerOn. + * + * @param[in] powerMode The new power mode + * + * @notapi + */ + void gdisp_lld_setpowermode(gdisp_powermode_t powerMode) { + if (GDISP.Powermode == powerMode) + return; + + switch(powerMode) { + case powerOff: + /* Code here */ + break; + case powerOn: + /* Code here */ + /* You may need this --- + if (GDISP.Powermode != powerSleep) + gdisp_lld_init(); + */ + break; + case powerSleep: + /* Code here */ + break; + default: + return; + } + + GDISP.Powermode = powerMode; + } #endif #if GDISP_HARDWARE_ORIENTATION || defined(__DOXYGEN__) -/** - * @brief Sets the orientation of the display. - * @note This may be ignored if not supported by the device. - * - * @param[in] newOrientation The new orientation - * - * @notapi - */ -void gdisp_lld_setorientation(gdisp_orientation_t newOrientation) { - /* Code here */ - /* if successful - GDISP1.Orientation = newOrientation; - */ -} + /** + * @brief Sets the orientation of the display. + * @note This may be ignored if not supported by the device. + * + * @param[in] newOrientation The new orientation + * + * @notapi + */ + void gdisp_lld_setorientation(gdisp_orientation_t newOrientation) { + if (GDISP.Orientation == newOrientation) + return; + + switch(newOrientation) { + case portrait: + /* Code here */ + GDISP.Height = SCREEN_HEIGHT; + GDISP.Width = SCREEN_WIDTH; + break; + case landscape: + /* Code here */ + GDISP.Height = SCREEN_WIDTH; + GDISP.Width = SCREEN_HEIGHT; + break; + case portraitInv: + /* Code here */ + GDISP.Height = SCREEN_HEIGHT; + GDISP.Width = SCREEN_WIDTH; + break; + case landscapeInv: + /* Code here */ + GDISP.Height = SCREEN_WIDTH; + GDISP.Width = SCREEN_HEIGHT; + break; + default: + return; + } + GDISP.Orientation = newOrientation; + } #endif #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__) @@ -241,9 +286,9 @@ void gdisp_lld_setorientation(gdisp_orientation_t newOrientation) { */ void gdisp_lld_fillarea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP1.Width || y >= GDISP1.Height) return; - if (x+cx > GDISP1.Width) cx = GDISP1.Width - x; - if (y+cy > GDISP1.Height) cy = GDISP1.Height - y; + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) cx = GDISP.Width - x; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; #endif /* Code here */ } @@ -262,8 +307,9 @@ void gdisp_lld_setorientation(gdisp_orientation_t newOrientation) { */ void gdisp_lld_blitarea(coord_t x, coord_t y, coord_t cx, coord_t cy, pixel_t *buffer) { #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP1.Width || y >= GDISP1.Height) return; - if (x+cx > GDISP1.Width || y+cy > GDISP1.Height) return; + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) return; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; #endif /* Code here */ } @@ -405,7 +451,7 @@ void gdisp_lld_setorientation(gdisp_orientation_t newOrientation) { */ color_t gdisp_lld_getpixelcolor(coord_t x, coord_t y) { #if GDISP_NEED_VALIDATION - if (x >= GDISP1.Width || y >= GDISP1.Height) return 0; + if (x >= GDISP.Width || y >= GDISP.Height) return 0; #endif /* Code here */ } @@ -427,9 +473,9 @@ void gdisp_lld_setorientation(gdisp_orientation_t newOrientation) { */ void gdisp_lld_verticalscroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) { #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP1.Width || y >= GDISP1.Height) return; - if (x+cx > GDISP1.Width) cx = GDISP1.Width - x; - if (y+cy > GDISP1.Height) cy = GDISP1.Height - y; + if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; + if (x+cx > GDISP.Width) cx = GDISP.Width - x; + if (y+cy > GDISP.Height) cy = GDISP.Height - y; #endif /* Code here */ } diff --git a/halext/templates/gdispXXXXX/gdisp_lld.h b/halext/templates/gdispXXXXX/gdisp_lld.h new file mode 100644 index 00000000..55241715 --- /dev/null +++ b/halext/templates/gdispXXXXX/gdisp_lld.h @@ -0,0 +1,166 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + --- + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes ChibiOS/RT, without being obliged to provide + the source code for any proprietary components. See the file exception.txt + for full details of how and when the exception can be applied. +*/ +/* + Concepts and parts of this file have been contributed by: + Joel Bodenmann aka Tectu -> Maintainer + Andrew Hannam aka inmarket -> framework + Badger -> console implementation and FSMC + Abhishek -> font rendering + Ben William -> fastMath and lcdDrawEllipse() + Dongxu Li aka dxli -> lcdDrawEllipse() filled option +*/ + +/** + * @file templates/gdisp_lld.h + * @brief GDISP Graphic Driver subsystem low level driver header template. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_H +#define _GDISP_LLD_H + +#if HAL_USE_GDISP || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Structure representing a GDISP driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. + */ +struct GDISPDriver { + /** + * @brief Width of the screen. + * @note Read-only. + */ + coord_t Width; + /** + * @brief Height of the screen. + * @note Read-only. + */ + coord_t Height; + /** + * @brief Current orientation of the screen. + * @note Read-only. + */ + gdisp_orientation_t Orientation; + /** + * @brief Current power mode of the screen. + * @note Read-only. + */ + gdisp_powermode_t Powermode; + + #if defined(GDISP_DRIVER_EXT_FIELDS) + GDISP_DRIVER_EXT_FIELDS + #endif + /* End of mandatory fields */ +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) + extern GDISPDriver GDISP; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /* Core functions */ + void gdisp_lld_init(void); + void gdisp_lld_setpowermode(gdisp_powermode_t powerMode); + void gdisp_lld_setorientation(gdisp_orientation_t newOrientation); + + /* Some of these functions will be implemented in software by the high level driver + depending on the GDISP_HARDWARE_XXX macros defined in gdisp_lld_config.h. + */ + + /* Drawing functions */ + void gdisp_lld_clear(color_t color); + void gdisp_lld_drawpixel(coord_t x, coord_t y, color_t color); + void gdisp_lld_drawline(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color); + void gdisp_lld_drawbox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); + void gdisp_lld_fillarea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); + void gdisp_lld_blitarea(coord_t x, coord_t y, coord_t cx, coord_t cy, pixel_t *buffer); + + /* Circular Drawing Functions */ + #if GDISP_NEED_CIRCLE + void gdisp_lld_drawcircle(coord_t x, coord_t y, coord_t radius, color_t color); + void gdisp_lld_fillcircle(coord_t x, coord_t y, coord_t radius, color_t color); + #endif + + #if GDISP_NEED_ELLIPSE + void gdisp_lld_drawellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color); + void gdisp_lld_fillellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color); + #endif + + /* Text Rendering Functions */ + #if GDISP_NEED_TEXT + void gdisp_lld_drawchar(coord_t x, coord_t y, char c, font_t font, color_t color); + void gdisp_lld_fillchar(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor); + #endif + + /* Pixel readback */ + #if GDISP_NEED_PIXELREAD + color_t gdisp_lld_getpixelcolor(coord_t x, coord_t y); + #endif + + /* Scrolling Function - clears the area scrolled out */ + #if GDISP_NEED_SCROLL + void gdisp_lld_verticalscroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor); + #endif + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_GDISP */ + +#endif /* _GDISP_LLD_H */ +/** @} */ diff --git a/halext/template/gdisp_lld.mk b/halext/templates/gdispXXXXX/gdisp_lld.mk similarity index 100% rename from halext/template/gdisp_lld.mk rename to halext/templates/gdispXXXXX/gdisp_lld.mk diff --git a/halext/template/gdisp_lld_config.h b/halext/templates/gdispXXXXX/gdisp_lld_config.h similarity index 100% rename from halext/template/gdisp_lld_config.h rename to halext/templates/gdispXXXXX/gdisp_lld_config.h diff --git a/halext/templates/gdispXXXXX/readme.txt b/halext/templates/gdispXXXXX/readme.txt new file mode 100644 index 00000000..f9129a3d --- /dev/null +++ b/halext/templates/gdispXXXXX/readme.txt @@ -0,0 +1,24 @@ +To use this driver template + 1. Copy this entire directory (including the directory itself) + into halext/drivers + 2. Rename the directory to match your hardware. + 3. Customise each file in the directory including the .mk file + and this file. An example for this file is below... + +------------------------------------------------------------------ +To use this driver: + +1. Add in your halconf.h: + a) #define HAL_USE_GDISP TRUE + b) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD + c) One (only) of: + #define LCD_USE_GPIO + #define LCD_USE_SPI + #define LCD_USE_FSMC + d) All of the following (with appropriate values): + #define SCREEN_WIDTH 128 + #define SCREEN_HEIGHT 128 + +2. To your makefile add the following lines: + include $(CHIBIOS)/os/halext/halext.mk + include $(CHIBIOS)/os/halext/drivers/gdispXXXXX/gdisp_lld.mk diff --git a/halext/templates/readme.txt b/halext/templates/readme.txt new file mode 100644 index 00000000..a2c5b7ef --- /dev/null +++ b/halext/templates/readme.txt @@ -0,0 +1,4 @@ +The following low level driver templates are available: + +GDISP: + gdispXXXXX - Generalised GDISP driver