ugfx/include/gdisp_lld.h

600 lines
20 KiB
C

/*
ChibiOS/RT - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS-LCD-Driver.
ChibiOS-LCD-Driver 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-LCD-Driver 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 <http://www.gnu.org/licenses/>.
*/
/**
* @file gdisp_lld.h
* @brief GDISP Graphic Driver subsystem low level driver header.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_H
#define _GDISP_LLD_H
#if HAL_USE_GDISP || defined(__DOXYGEN__)
/*===========================================================================*/
/* Low level driver configuration needs */
/*===========================================================================*/
/**
* @name GDISP low level driver more complex functionality to be compiled
* @{
*/
/**
* @brief Should all operations be clipped to the screen and colors validated.
* @details Defaults to TRUE.
* @note If this is FALSE, any operations that extend beyond the
* edge of the screen will have undefined results. Any
* out-of-range colors will produce undefined results.
* @note If defined then all low level and high level driver routines
* must check the validity of inputs and do something sensible
* if they are out of range. It doesn't have to be efficient,
* just valid.
*/
#ifndef GDISP_NEED_VALIDATION
#define GDISP_NEED_VALIDATION TRUE
#endif
/**
* @brief Are circle functions needed.
* @details Defaults to TRUE
*/
#ifndef GDISP_NEED_CIRCLE
#define GDISP_NEED_CIRCLE TRUE
#endif
/**
* @brief Are ellipse functions needed.
* @details Defaults to TRUE
*/
#ifndef GDISP_NEED_ELLIPSE
#define GDISP_NEED_ELLIPSE TRUE
#endif
/**
* @brief Are text functions needed.
* @details Defaults to TRUE
*/
#ifndef GDISP_NEED_TEXT
#define GDISP_NEED_TEXT TRUE
#endif
/**
* @brief Is scrolling needed.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_SCROLL
#define GDISP_NEED_SCROLL FALSE
#endif
/**
* @brief Is the capability to read pixels back needed.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_PIXELREAD
#define GDISP_NEED_PIXELREAD FALSE
#endif
/**
* @brief Control some aspect of the drivers operation.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_CONTROL
#define GDISP_NEED_CONTROL FALSE
#endif
/**
* @brief Query some aspect of the drivers operation.
* @details Defaults to TRUE
*/
#ifndef GDISP_NEED_QUERY
#define GDISP_NEED_QUERY TRUE
#endif
/**
* @brief Is the messaging api interface required.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_MSGAPI
#define GDISP_NEED_MSGAPI FALSE
#endif
/** @} */
/*===========================================================================*/
/* Include the low level driver configuration information */
/*===========================================================================*/
#include "gdisp_lld_config.h"
/*===========================================================================*/
/* Constants. */
/*===========================================================================*/
/**
* @brief Driver Control Constants
* @detail Unsupported control codes are ignored.
* @note The value parameter should always be typecast to (void *).
* @note There are some predefined and some specific to the low level driver.
* @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
* GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
* GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
* that only supports off/on anything other
* than zero is on.
* GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
* GDISP_CONTROL_LLD - Low level driver control constants start at
* this value.
*/
#define GDISP_CONTROL_POWER 0
#define GDISP_CONTROL_ORIENTATION 1
#define GDISP_CONTROL_BACKLIGHT 2
#define GDISP_CONTROL_CONTRAST 3
#define GDISP_CONTROL_LLD 1000
/**
* @brief Driver Query Constants
* @detail Unsupported query codes return (void *)-1.
* @note There are some predefined and some specific to the low level driver.
* @note The result should be typecast the required type.
* @note GDISP_QUERY_WIDTH - Gets the width of the screen
* GDISP_QUERY_HEIGHT - Gets the height of the screen
* GDISP_QUERY_POWER - Get the current powermode
* GDISP_QUERY_ORIENTATION - Get the current orientation
* GDISP_QUERY_BACKLIGHT - Get the backlight state (0 to 100)
* GDISP_QUERY_CONTRAST - Get the contrast.
* GDISP_QUERY_LLD - Low level driver control constants start at
* this value.
*/
#define GDISP_QUERY_WIDTH 0
#define GDISP_QUERY_HEIGHT 1
#define GDISP_QUERY_POWER 2
#define GDISP_QUERY_ORIENTATION 3
#define GDISP_QUERY_BACKLIGHT 4
#define GDISP_QUERY_CONTRAST 5
#define GDISP_QUERY_LLD 1000
/**
* @brief Driver Pixel Format Constants
*/
#define GDISP_PIXELFORMAT_RGB565 565
#define GDISP_PIXELFORMAT_RGB888 888
#define GDISP_PIXELFORMAT_RGB444 444
#define GDISP_PIXELFORMAT_RGB332 332
#define GDISP_PIXELFORMAT_RGB666 666
#define GDISP_PIXELFORMAT_CUSTOM 99999
#define GDISP_PIXELFORMAT_ERROR 88888
/*===========================================================================*/
/* Error checks. */
/*===========================================================================*/
/**
* @name GDISP hardware accelerated support
* @{
*/
/**
* @brief Hardware accelerated line drawing.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_LINES
#define GDISP_HARDWARE_LINES FALSE
#endif
/**
* @brief Hardware accelerated screen clears.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_CLEARS
#define GDISP_HARDWARE_CLEARS FALSE
#endif
/**
* @brief Hardware accelerated rectangular fills.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_FILLS
#define GDISP_HARDWARE_FILLS FALSE
#endif
/**
* @brief Hardware accelerated fills from an image.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_BITFILLS
#define GDISP_HARDWARE_BITFILLS FALSE
#endif
/**
* @brief Hardware accelerated circles.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_CIRCLES
#define GDISP_HARDWARE_CIRCLES FALSE
#endif
/**
* @brief Hardware accelerated filled circles.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_CIRCLEFILLS
#define GDISP_HARDWARE_CIRCLEFILLS FALSE
#endif
/**
* @brief Hardware accelerated ellipses.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_ELLIPSES
#define GDISP_HARDWARE_ELLIPSES FALSE
#endif
/**
* @brief Hardware accelerated filled ellipses.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_ELLIPSEFILLS
#define GDISP_HARDWARE_ELLIPSEFILLS FALSE
#endif
/**
* @brief Hardware accelerated text drawing.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_TEXT
#define GDISP_HARDWARE_TEXT FALSE
#endif
/**
* @brief Hardware accelerated text drawing with a filled background.
* @details If set to @p FALSE software emulation is used.
*/
#ifndef GDISP_HARDWARE_TEXTFILLS
#define GDISP_HARDWARE_TEXTFILLS FALSE
#endif
/**
* @brief Hardware accelerated scrolling.
* @details If set to @p FALSE there is no support for scrolling.
*/
#ifndef GDISP_HARDWARE_SCROLL
#define GDISP_HARDWARE_SCROLL FALSE
#endif
/**
* @brief Reading back of pixel values.
* @details If set to @p FALSE there is no support for pixel read-back.
*/
#ifndef GDISP_HARDWARE_PIXELREAD
#define GDISP_HARDWARE_PIXELREAD FALSE
#endif
/**
* @brief The driver supports one or more control commands.
* @details If set to @p FALSE there is no support for control commands.
*/
#ifndef GDISP_HARDWARE_CONTROL
#define GDISP_HARDWARE_CONTROL FALSE
#endif
/**
* @brief The driver supports a non-standard query.
* @details If set to @p FALSE there is no support for non-standard queries.
*/
#ifndef GDISP_HARDWARE_QUERY
#define GDISP_HARDWARE_QUERY FALSE
#endif
/** @} */
/**
* @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.
*/
#ifndef GDISP_SOFTWARE_TEXTFILLDRAW
#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE
#endif
/**
* @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.
*/
#ifndef GDISP_SOFTWARE_TEXTBLITCOLUMN
#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE
#endif
/** @} */
/**
* @name GDISP pixel format choices
* @{
*/
/**
* @brief The native pixel format for this device
* @note Should be set to one of the following:
* GDISP_PIXELFORMAT_RGB565
* GDISP_PIXELFORMAT_RGB888
* GDISP_PIXELFORMAT_RGB444
* GDISP_PIXELFORMAT_RGB332
* GDISP_PIXELFORMAT_RGB666
* GDISP_PIXELFORMAT_CUSTOM
* @note If you set 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.
*/
#ifndef GDISP_PIXELFORMAT
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR
#endif
/**
* @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.
*/
#ifndef GDISP_PACKED_PIXELS
#define GDISP_PACKED_PIXELS FALSE
#endif
/**
* @brief Do lines of pixels require packing for a blit
* @note Ignored if GDISP_PACKED_PIXELS is FALSE
*/
#ifndef GDISP_PACKED_LINES
#define GDISP_PACKED_LINES FALSE
#endif
/** @} */
/*===========================================================================*/
/* Define the macro's for the various pixel formats */
/*===========================================================================*/
#if defined(__DOXYGEN__)
/**
* @brief The color of a pixel.
*/
typedef uint16_t color_t;
/**
* @brief Convert a number (of any type) to a color_t.
* @details Masks any invalid bits in the color
*/
#define COLOR(c) ((color_t)(c))
/**
* @brief Does the color_t type contain invalid bits that need masking.
*/
#define MASKCOLOR FALSE
/**
* @brief Convert red, green, blue (each 0 to 255) into a color value.
*/
#define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF8)<<8) | (((g) & 0xFC)<<3) | (((b) & 0xF8)>>3)))
/**
* @brief Convert a 6 digit HTML code (hex) into a color value.
*/
#define HTML2COLOR(h) ((color_t)((((h) & 0xF80000)>>8) | (((h) & 0x00FC00)>>5) | (((h) & 0x0000F8)>>3)))
/**
* @brief Extract the red component (0 to 255) of a color value.
*/
#define RED_OF(c) (((c) & 0xF800)>>8)
/**
* @brief Extract the green component (0 to 255) of a color value.
*/
#define GREEN_OF(c) (((c)&0x007E)>>3)
/**
* @brief Extract the blue component (0 to 255) of a color value.
*/
#define BLUE_OF(c) (((c)&0x001F)<<3)
#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565
typedef uint16_t color_t;
#define COLOR(c) ((color_t)(c))
#define MASKCOLOR FALSE
#define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF8)<<8) | (((g) & 0xFC)<<3) | (((b) & 0xF8)>>3)))
#define HTML2COLOR(h) ((color_t)((((h) & 0xF80000)>>8) | (((h) & 0x00FC00)>>5) | (((h) & 0x0000F8)>>3)))
#define RED_OF(c) (((c) & 0xF800)>>8)
#define GREEN_OF(c) (((c)&0x007E)>>3)
#define BLUE_OF(c) (((c)&0x001F)<<3)
#define RGB565CONVERT(red, green, blue) (uint16_t)( (( red >> 3 ) << 11 ) | (( green >> 2 ) << 5 ) | ( blue >> 3 ))
#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888
typedef uint32_t color_t;
#define COLOR(c) ((color_t)(((c) & 0xFFFFFF)))
#define MASKCOLOR TRUE
#define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xFF)<<16) | (((g) & 0xFF) << 8) | ((b) & 0xFF)))
#define HTML2COLOR(h) ((color_t)(h))
#define RED_OF(c) (((c) & 0xFF0000)>>16)
#define GREEN_OF(c) (((c)&0x00FF00)>>8)
#define BLUE_OF(c) ((c)&0x0000FF)
#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB444
typedef uint16_t color_t;
#define COLOR(c) ((color_t)(((c) & 0x0FFF)))
#define MASKCOLOR TRUE
#define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF0)<<4) | ((g) & 0xF0) | (((b) & 0xF0)>>4)))
#define HTML2COLOR(h) ((color_t)((((h) & 0xF00000)>>12) | (((h) & 0x00F000)>>8) | (((h) & 0x0000F0)>>4)))
#define RED_OF(c) (((c) & 0x0F00)>>4)
#define GREEN_OF(c) ((c)&0x00F0)
#define BLUE_OF(c) (((c)&0x000F)<<4)
#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB332
typedef uint8_t color_t;
#define COLOR(c) ((color_t)(c))
#define MASKCOLOR FALSE
#define RGB2COLOR(r,g,b) ((color_t)(((r) & 0xE0) | (((g) & 0xE0)>>3) | (((b) & 0xC0)>>6)))
#define HTML2COLOR(h) ((color_t)((((h) & 0xE00000)>>16) | (((h) & 0x00E000)>>11) | (((h) & 0x0000C0)>>6)))
#define RED_OF(c) ((c) & 0xE0)
#define GREEN_OF(c) (((c)&0x1C)<<3)
#define BLUE_OF(c) (((c)&0x03)<<6)
#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB666
typedef uint32_t color_t;
#define COLOR(c) ((color_t)(((c) & 0x03FFFF)))
#define MASKCOLOR TRUE
#define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xFC)<<10) | (((g) & 0xFC)<<4) | (((b) & 0xFC)>>2)))
#define HTML2COLOR(h) ((color_t)((((h) & 0xFC0000)>>6) | (((h) & 0x00FC00)>>4) | (((h) & 0x0000FC)>>2)))
#define RED_OF(c) (((c) & 0x03F000)>>12)
#define GREEN_OF(c) (((c)&0x00FC00)>>8)
#define BLUE_OF(c) (((c)&0x00003F)<<2)
#elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM
#error "GDISP: No supported pixel format has been specified."
#endif
/* Verify information for packed pixels and define a non-packed pixel macro */
#if !GDISP_PACKED_PIXELS
#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 GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 \
&& GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB444 \
&& GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB666 \
&& GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM
#error "GDISP: A packed pixel format has been specified for an unsupported pixel format."
#endif
#if GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL
#error "GDISP: Hardware scrolling is wanted but not supported."
#endif
#if GDISP_NEED_PIXELREAD && !GDISP_HARDWARE_PIXELREAD
#error "GDISP: Pixel read-back is wanted but not supported."
#endif
/*===========================================================================*/
/* Driver types. */
/*===========================================================================*/
/**
* @brief The type for a coordinate or length on the screen.
*/
typedef uint16_t coord_t;
/**
* @brief The type of a pixel.
*/
typedef color_t pixel_t;
/**
* @brief The type of a font.
*/
typedef const struct font *font_t;
/**
* @brief Type for the screen orientation.
*/
typedef enum orientation {portrait, landscape, portraitInv, landscapeInv} gdisp_orientation_t;
/**
* @brief Type for the available power modes for the screen.
*/
typedef enum powermode {powerOff, powerSleep, powerOn} gdisp_powermode_t;
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifndef GDISP_LLD_VMT
/* Special magic stuff for the VMT driver */
#define GDISP_LLD_VMT(x) GDISP_LLD(x)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Core functions */
extern bool_t GDISP_LLD(init)(void);
/* 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 */
extern void GDISP_LLD_VMT(clear)(color_t color);
extern void GDISP_LLD_VMT(drawpixel)(coord_t x, coord_t y, color_t color);
extern void GDISP_LLD_VMT(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
extern void GDISP_LLD_VMT(blitarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, const pixel_t *buffer);
extern void GDISP_LLD_VMT(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
/* Circular Drawing Functions */
#if GDISP_NEED_CIRCLE
extern void GDISP_LLD_VMT(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color);
extern void GDISP_LLD_VMT(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color);
#endif
#if GDISP_NEED_ELLIPSE
extern void GDISP_LLD_VMT(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
extern void GDISP_LLD_VMT(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
#endif
/* Text Rendering Functions */
#if GDISP_NEED_TEXT
extern void GDISP_LLD_VMT(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color);
extern void GDISP_LLD_VMT(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
extern color_t GDISP_LLD_VMT(getpixelcolor)(coord_t x, coord_t y);
#endif
/* Scrolling Function - clears the area scrolled out */
#if GDISP_NEED_SCROLL
extern void GDISP_LLD_VMT(verticalscroll)(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
#endif
/* Set driver specific control */
#if GDISP_NEED_CONTROL
extern void GDISP_LLD_VMT(control)(unsigned what, void *value);
#endif
/* Query driver specific data */
#if GDISP_NEED_QUERY
extern void *GDISP_LLD_VMT(query)(unsigned what);
#endif
/* Messaging API */
#if GDISP_NEED_MSGAPI
#include "gdisp_lld_msgs.h"
extern void GDISP_LLD(msgdispatch)(gdisp_lld_msg_t *msg);
#endif
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_GDISP */
#endif /* _GDISP_LLD_H */
/** @} */