aboutsummaryrefslogtreecommitdiffstats
path: root/src/gdisp/gdisp_driver.h
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2015-01-21 17:26:24 +1000
committerinmarket <andrewh@inmarket.com.au>2015-01-21 17:26:24 +1000
commitfa8167b94d13e94a6cb953e7f549a89f155f77c6 (patch)
tree8c33f78c45ca72ac2653327607f1d7caed668c5e /src/gdisp/gdisp_driver.h
parent34939386d7390b0876973a1969f336b814313a22 (diff)
downloaduGFX-fa8167b94d13e94a6cb953e7f549a89f155f77c6.tar.gz
uGFX-fa8167b94d13e94a6cb953e7f549a89f155f77c6.tar.bz2
uGFX-fa8167b94d13e94a6cb953e7f549a89f155f77c6.zip
Big file rename to reduce problems with brain-dead IDE's that don't handle project file hierarchies well.
Naming is more consistent with the new scheme. May affect some third party drivers (header file renames).
Diffstat (limited to 'src/gdisp/gdisp_driver.h')
-rw-r--r--src/gdisp/gdisp_driver.h1070
1 files changed, 1070 insertions, 0 deletions
diff --git a/src/gdisp/gdisp_driver.h b/src/gdisp/gdisp_driver.h
new file mode 100644
index 00000000..085e248f
--- /dev/null
+++ b/src/gdisp/gdisp_driver.h
@@ -0,0 +1,1070 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file src/gdisp/gdisp_driver.h
+ * @brief GDISP Graphic Driver subsystem low level driver header.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_H
+#define _GDISP_LLD_H
+
+#if GFX_USE_GDISP
+
+// Include the GDRIVER infrastructure
+#include "src/gdriver/gdriver.h"
+
+// Are we currently compiling the driver itself?
+#if defined(GDISP_DRIVER_VMT)
+ #define IN_DRIVER TRUE
+#else
+ #define IN_DRIVER FALSE
+#endif
+
+// Is this a multiple driver situation?
+#if defined(GDISP_DRIVER_LIST)
+ #define IS_MULTIPLE TRUE
+#else
+ #define IS_MULTIPLE FALSE
+#endif
+
+// Do we need to use VMT calling rather than direct calls to the driver?
+#if IS_MULTIPLE || GDISP_NEED_PIXMAP
+ #define USE_VMT TRUE
+#else
+ #define USE_VMT FALSE
+#endif
+
+// Are we in the pixmap virtual driver
+#ifndef IN_PIXMAP_DRIVER
+ #define IN_PIXMAP_DRIVER FALSE
+#endif
+
+//------------------------------------------------------------------------------------------------------------
+
+// Our special auto-detect hardware code which uses the VMT.
+#define HARDWARE_AUTODETECT 2
+
+#if USE_VMT && !IN_DRIVER
+ // Multiple controllers the default is to hardware detect
+ #define HARDWARE_DEFAULT HARDWARE_AUTODETECT
+#else
+ // The default is not to include code functions that aren't needed
+ #define HARDWARE_DEFAULT FALSE
+#endif
+
+//------------------------------------------------------------------------------------------------------------
+
+/**
+ * @name GDISP hardware accelerated support
+ * @{
+ */
+ /**
+ * @brief The display hardware can benefit from being de-initialized when usage is complete.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ * @note This is most useful for displays such as remote network displays.
+ */
+ #ifndef GDISP_HARDWARE_DEINIT
+ #define GDISP_HARDWARE_DEINIT HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief The display hardware can benefit from being flushed.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ * @note Some controllers ** require ** the application to flush
+ */
+ #ifndef GDISP_HARDWARE_FLUSH
+ #define GDISP_HARDWARE_FLUSH HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware streaming writing is supported.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by each driver
+ */
+ #ifndef GDISP_HARDWARE_STREAM_WRITE
+ #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware streaming reading of the display surface is supported.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ *
+ */
+ #ifndef GDISP_HARDWARE_STREAM_READ
+ #define GDISP_HARDWARE_STREAM_READ HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware supports setting the cursor position within the stream window.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ * @note This is used to optimise setting of individual pixels within a stream window.
+ * It should therefore not be implemented unless it is cheaper than just setting
+ * a new window.
+ */
+ #ifndef GDISP_HARDWARE_STREAM_POS
+ #define GDISP_HARDWARE_STREAM_POS HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated draw pixel.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver
+ */
+ #ifndef GDISP_HARDWARE_DRAWPIXEL
+ #define GDISP_HARDWARE_DRAWPIXEL HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated screen clears.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ * @note This clears the entire display surface regardless of the clipping area currently set
+ */
+ #ifndef GDISP_HARDWARE_CLEARS
+ #define GDISP_HARDWARE_CLEARS HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated rectangular fills.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ */
+ #ifndef GDISP_HARDWARE_FILLS
+ #define GDISP_HARDWARE_FILLS HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated fills from an image.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ */
+ #ifndef GDISP_HARDWARE_BITFILLS
+ #define GDISP_HARDWARE_BITFILLS HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Hardware accelerated scrolling.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ */
+ #ifndef GDISP_HARDWARE_SCROLL
+ #define GDISP_HARDWARE_SCROLL HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief Reading back of pixel values.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ */
+ #ifndef GDISP_HARDWARE_PIXELREAD
+ #define GDISP_HARDWARE_PIXELREAD HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief The driver supports one or more control commands.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ */
+ #ifndef GDISP_HARDWARE_CONTROL
+ #define GDISP_HARDWARE_CONTROL HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief The driver supports a non-standard query.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ */
+ #ifndef GDISP_HARDWARE_QUERY
+ #define GDISP_HARDWARE_QUERY HARDWARE_DEFAULT
+ #endif
+
+ /**
+ * @brief The driver supports a clipping in hardware.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
+ * @note If this is defined the driver must perform its own clipping on all calls to
+ * the driver and respond appropriately if a parameter is outside the display area.
+ * @note If this is not defined then the software ensures that all calls to the
+ * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION
+ * has been set).
+ */
+ #ifndef GDISP_HARDWARE_CLIP
+ #define GDISP_HARDWARE_CLIP HARDWARE_DEFAULT
+ #endif
+/** @} */
+
+//------------------------------------------------------------------------------------------------------------
+
+// For pixmaps certain routines MUST not be FALSE as they are needed for pixmap drawing
+// Similarly some routines MUST not be TRUE as pixmap's don't provide them.
+#if GDISP_NEED_PIXMAP && !IN_DRIVER
+ #if !GDISP_HARDWARE_DEINIT
+ #undef GDISP_HARDWARE_DEINIT
+ #define GDISP_HARDWARE_DEINIT HARDWARE_AUTODETECT
+ #endif
+ #if !GDISP_HARDWARE_DRAWPIXEL
+ #undef GDISP_HARDWARE_DRAWPIXEL
+ #define GDISP_HARDWARE_DRAWPIXEL HARDWARE_AUTODETECT
+ #endif
+ #if !GDISP_HARDWARE_PIXELREAD
+ #undef GDISP_HARDWARE_PIXELREAD
+ #define GDISP_HARDWARE_PIXELREAD HARDWARE_AUTODETECT
+ #endif
+ #if !GDISP_HARDWARE_CONTROL
+ #undef GDISP_HARDWARE_CONTROL
+ #define GDISP_HARDWARE_CONTROL HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_FLUSH == TRUE
+ #undef GDISP_HARDWARE_FLUSH
+ #define GDISP_HARDWARE_FLUSH HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_STREAM_WRITE == TRUE
+ #undef GDISP_HARDWARE_STREAM_WRITE
+ #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_STREAM_READ == TRUE
+ #undef GDISP_HARDWARE_STREAM_READ
+ #define GDISP_HARDWARE_STREAM_READ HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_CLEARS == TRUE
+ #undef GDISP_HARDWARE_CLEARS
+ #define GDISP_HARDWARE_CLEARS HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_FILLS == TRUE
+ #undef GDISP_HARDWARE_FILLS
+ #define GDISP_HARDWARE_FILLS HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_BITFILLS == TRUE
+ #undef GDISP_HARDWARE_BITFILLS
+ #define GDISP_HARDWARE_BITFILLS HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_SCROLL == TRUE
+ #undef GDISP_HARDWARE_SCROLL
+ #define GDISP_HARDWARE_SCROLL HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_QUERY == TRUE
+ #undef GDISP_HARDWARE_QUERY
+ #define GDISP_HARDWARE_QUERY HARDWARE_AUTODETECT
+ #endif
+ #if GDISP_HARDWARE_CLIP == TRUE
+ #undef GDISP_HARDWARE_CLIP
+ #define GDISP_HARDWARE_CLIP HARDWARE_AUTODETECT
+ #endif
+#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
+
+/* Support routine for packed pixel formats */
+#if !defined(gdispPackPixels) || defined(__DOXYGEN__)
+ /**
+ * @brief Pack a pixel into a pixel buffer.
+ * @note This function performs no buffer boundary checking
+ * regardless of whether GDISP_NEED_CLIP has been specified.
+ *
+ * @param[in] buf The buffer to put the pixel in
+ * @param[in] cx The width of a pixel line
+ * @param[in] x, y The location of the pixel to place
+ * @param[in] color The color to put into the buffer
+ *
+ * @api
+ */
+ void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color);
+#endif
+
+//------------------------------------------------------------------------------------------------------------
+
+struct GDisplay {
+ struct GDriver d; // This must be the first element
+ #define gvmt(g) ((const GDISPVMT const *)((g)->d.vmt)) // For ease of access to the vmt member
+
+ struct GDISPControl {
+ coord_t Width;
+ coord_t Height;
+ orientation_t Orientation;
+ powermode_t Powermode;
+ uint8_t Backlight;
+ uint8_t Contrast;
+ } g;
+
+ void * priv; // A private area just for the drivers use.
+ void * board; // A private area just for the board interfaces use.
+
+ uint8_t systemdisplay;
+ uint8_t controllerdisplay;
+ uint16_t flags;
+ #define GDISP_FLG_INSTREAM 0x0001 // We are in a user based stream operation
+ #define GDISP_FLG_SCRSTREAM 0x0002 // The stream area currently covers the whole screen
+ #define GDISP_FLG_DRIVER 0x0004 // This flags and above are for use by the driver
+
+ // Multithread Mutex
+ #if GDISP_NEED_MULTITHREAD
+ gfxMutex mutex;
+ #endif
+
+ // Software clipping
+ #if GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
+ coord_t clipx0, clipy0;
+ coord_t clipx1, clipy1; /* not inclusive */
+ #endif
+
+ // Driver call parameters
+ struct {
+ coord_t x, y;
+ coord_t cx, cy;
+ coord_t x1, y1;
+ coord_t x2, y2;
+ color_t color;
+ void *ptr;
+ } p;
+
+ // In call working buffers
+
+ #if GDISP_NEED_TEXT
+ // Text rendering parameters
+ struct {
+ font_t font;
+ color_t color;
+ color_t bgcolor;
+ coord_t clipx0, clipy0;
+ coord_t clipx1, clipy1;
+ } t;
+ #endif
+ #if GDISP_LINEBUF_SIZE != 0 && ((GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL) || (!GDISP_HARDWARE_STREAM_WRITE && GDISP_HARDWARE_BITFILLS))
+ // A pixel line buffer
+ color_t linebuf[GDISP_LINEBUF_SIZE];
+ #endif
+};
+
+typedef struct GDISPVMT {
+ GDriverVMT d;
+ #define GDISP_VFLG_DYNAMICONLY 0x0001 // This display should never be statically initialised
+ #define GDISP_VFLG_PIXMAP 0x0002 // This is a pixmap display
+ bool_t (*init)(GDisplay *g);
+ void (*deinit)(GDisplay *g);
+ void (*writestart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ void (*writepos)(GDisplay *g); // Uses p.x,p.y
+ void (*writecolor)(GDisplay *g); // Uses p.color
+ void (*writestop)(GDisplay *g); // Uses no parameters
+ void (*readstart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ color_t (*readcolor)(GDisplay *g); // Uses no parameters
+ void (*readstop)(GDisplay *g); // Uses no parameters
+ void (*pixel)(GDisplay *g); // Uses p.x,p.y p.color
+ void (*clear)(GDisplay *g); // Uses p.color
+ void (*fill)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.color
+ void (*blit)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer)
+ color_t (*get)(GDisplay *g); // Uses p.x,p.y
+ void (*vscroll)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color
+ void (*control)(GDisplay *g); // Uses p.x (=what) p.ptr (=value)
+ void *(*query)(GDisplay *g); // Uses p.x (=what);
+ void (*setclip)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ void (*flush)(GDisplay *g); // Uses no parameters
+} GDISPVMT;
+
+//------------------------------------------------------------------------------------------------------------
+
+// Do we need function definitions or macro's (via the VMT)
+#if IN_DRIVER || !USE_VMT || defined(__DOXYGEN__)
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ // Should the driver routines should be static or not
+ #if USE_VMT
+ #define LLDSPEC static
+ #else
+ #define LLDSPEC
+ #endif
+
+ /**
+ * @brief Initialize the driver.
+ * @return TRUE if successful.
+ * @param[in] g The driver structure
+ * @param[out] g->g The driver must fill in the GDISPControl structure
+ */
+ LLDSPEC bool_t gdisp_lld_init(GDisplay *g);
+
+ #if GDISP_HARDWARE_DEINIT || defined(__DOXYGEN__)
+ /**
+ * @brief The driver is being de-initialized
+ * @pre GDISP_HARDWARE_FLUSH is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ */
+ LLDSPEC void gdisp_lld_deinit(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_FLUSH || defined(__DOXYGEN__)
+ /**
+ * @brief Flush the current drawing operations to the display
+ * @pre GDISP_HARDWARE_FLUSH is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_flush(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_STREAM_WRITE || defined(__DOXYGEN__)
+ /**
+ * @brief Start a streamed write operation
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note g->p.x,g->p.y The window position
+ * @note g->p.cx,g->p.cy The window size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note Streaming operations that wrap the defined window have
+ * undefined results.
+ * @note This must be followed by a call to @p gdisp_lld_write_pos() if GDISP_HARDWARE_STREAM_POS is TRUE.
+ */
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g);
+
+ /**
+ * @brief Send a pixel to the current streaming position and then increment that position
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note g->p.color The color to display at the curent position
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g);
+
+ /**
+ * @brief End the current streaming write operation
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g);
+
+ #if GDISP_HARDWARE_STREAM_POS || defined(__DOXYGEN__)
+ /**
+ * @brief Change the current position within the current streaming window
+ * @pre GDISP_HARDWARE_STREAM_POS is TRUE and GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The new position (which will always be within the existing stream window)
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g);
+ #endif
+ #endif
+
+ #if GDISP_HARDWARE_STREAM_READ || defined(__DOXYGEN__)
+ /**
+ * @brief Start a streamed read operation
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The window position
+ * @param[in] g->p.cx,g->p.cy The window size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note Streaming operations that wrap the defined window have
+ * undefined results.
+ */
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g);
+
+ /**
+ * @brief Read a pixel from the current streaming position and then increment that position
+ * @return The color at the current position
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g);
+
+ /**
+ * @brief End the current streaming operation
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_DRAWPIXEL || defined(__DOXYGEN__)
+ /**
+ * @brief Draw a pixel
+ * @pre GDISP_HARDWARE_DRAWPIXEL is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The pixel position
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
+ /**
+ * @brief Clear the screen using the defined color
+ * @pre GDISP_HARDWARE_CLEARS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_clear(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
+ /**
+ * @brief Fill an area with a single color
+ * @pre GDISP_HARDWARE_FILLS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
+ /**
+ * @brief Fill an area using a bitmap
+ * @pre GDISP_HARDWARE_BITFILLS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.x1,g->p.y1 The starting position in the bitmap
+ * @param[in] g->p.x2 The width of a bitmap line
+ * @param[in] g->p.ptr The pointer to the bitmap
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g);
+ #endif
+
+ #if GDISP_HARDWARE_PIXELREAD || defined(__DOXYGEN__)
+ /**
+ * @brief Read a pixel from the display
+ * @return The color at the defined position
+ * @pre GDISP_HARDWARE_PIXELREAD is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The pixel position
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g);
+ #endif
+
+ #if (GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL) || defined(__DOXYGEN__)
+ /**
+ * @brief Scroll an area of the screen
+ * @pre GDISP_HARDWARE_SCROLL is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.y1 The number of lines to scroll (positive or negative)
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note This can be easily implemented if the hardware supports
+ * display area to display area copying.
+ * @note Clearing the exposed area on the scroll operation is not
+ * needed as the high level code handles this.
+ */
+ LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g);
+ #endif
+
+ #if (GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL) || defined(__DOXYGEN__)
+ /**
+ * @brief Control some feature of the hardware
+ * @pre GDISP_HARDWARE_CONTROL is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x The operation to perform
+ * @param[in] g->p.ptr The operation parameter
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_control(GDisplay *g);
+ #endif
+
+ #if (GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY) || defined(__DOXYGEN__)
+ /**
+ * @brief Query some feature of the hardware
+ * @return The information requested (typecast as void *)
+ * @pre GDISP_HARDWARE_QUERY is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x What to query
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void *gdisp_lld_query(GDisplay *g); // Uses p.x (=what);
+ #endif
+
+ #if (GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)) || defined(__DOXYGEN__)
+ /**
+ * @brief Set the hardware clipping area
+ * @pre GDISP_HARDWARE_CLIP is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_set_clip(GDisplay *g);
+ #endif
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+#else
+ #define gdisp_lld_init(g) gvmt(g)->init(g)
+ #define gdisp_lld_deinit(g) gvmt(g)->deinit(g)
+ #define gdisp_lld_flush(g) gvmt(g)->flush(g)
+ #define gdisp_lld_write_start(g) gvmt(g)->writestart(g)
+ #define gdisp_lld_write_pos(g) gvmt(g)->writepos(g)
+ #define gdisp_lld_write_color(g) gvmt(g)->writecolor(g)
+ #define gdisp_lld_write_stop(g) gvmt(g)->writestop(g)
+ #define gdisp_lld_read_start(g) gvmt(g)->readstart(g)
+ #define gdisp_lld_read_color(g) gvmt(g)->readcolor(g)
+ #define gdisp_lld_read_stop(g) gvmt(g)->readstop(g)
+ #define gdisp_lld_draw_pixel(g) gvmt(g)->pixel(g)
+ #define gdisp_lld_clear(g) gvmt(g)->clear(g)
+ #define gdisp_lld_fill_area(g) gvmt(g)->fill(g)
+ #define gdisp_lld_blit_area(g) gvmt(g)->blit(g)
+ #define gdisp_lld_get_pixel_color(g) gvmt(g)->get(g)
+ #define gdisp_lld_vertical_scroll(g) gvmt(g)->vscroll(g)
+ #define gdisp_lld_control(g) gvmt(g)->control(g)
+ #define gdisp_lld_query(g) gvmt(g)->query(g)
+ #define gdisp_lld_set_clip(g) gvmt(g)->setclip(g)
+#endif
+
+//------------------------------------------------------------------------------------------------------------
+
+// If compiling the driver then build the VMT and set the low level driver color macros.
+#if IN_DRIVER
+
+ // Make sure the driver has a valid model
+ #if !GDISP_HARDWARE_STREAM_WRITE && !GDISP_HARDWARE_DRAWPIXEL
+ #error "GDISP Driver: Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be TRUE"
+ #endif
+
+ // If we are not using multiple displays then hard-code the VMT name (except for the pixmap driver)
+ #if !IS_MULTIPLE && !IN_PIXMAP_DRIVER
+ #undef GDISP_DRIVER_VMT
+ #define GDISP_DRIVER_VMT GDISPVMT_OnlyOne
+ #endif
+
+ // Default the flags if the driver doesn't specify any
+ #ifndef GDISP_DRIVER_VMT_FLAGS
+ #define GDISP_DRIVER_VMT_FLAGS 0
+ #endif
+
+ // Routines needed by the general driver VMT
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ bool_t _gdispInitDriver(GDriver *g, void *param, unsigned driverinstance, unsigned systeminstance);
+ void _gdispPostInitDriver(GDriver *g);
+ void _gdispDeInitDriver(GDriver *g);
+ #ifdef __cplusplus
+ }
+ #endif
+
+ // Build the VMT
+ const GDISPVMT const GDISP_DRIVER_VMT[1] = {{
+ { GDRIVER_TYPE_DISPLAY, 0, sizeof(GDisplay), _gdispInitDriver, _gdispPostInitDriver, _gdispDeInitDriver },
+ gdisp_lld_init,
+ #if GDISP_HARDWARE_DEINIT
+ gdisp_lld_deinit,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_STREAM_WRITE
+ gdisp_lld_write_start,
+ #if GDISP_HARDWARE_STREAM_POS
+ gdisp_lld_write_pos,
+ #else
+ 0,
+ #endif
+ gdisp_lld_write_color,
+ gdisp_lld_write_stop,
+ #else
+ 0, 0, 0, 0,
+ #endif
+ #if GDISP_HARDWARE_STREAM_READ
+ gdisp_lld_read_start,
+ gdisp_lld_read_color,
+ gdisp_lld_read_stop,
+ #else
+ 0, 0, 0,
+ #endif
+ #if GDISP_HARDWARE_DRAWPIXEL
+ gdisp_lld_draw_pixel,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CLEARS
+ gdisp_lld_clear,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_FILLS
+ gdisp_lld_fill_area,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_BITFILLS
+ gdisp_lld_blit_area,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_PIXELREAD
+ gdisp_lld_get_pixel_color,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL
+ gdisp_lld_vertical_scroll,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL
+ gdisp_lld_control,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY
+ gdisp_lld_query,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
+ gdisp_lld_set_clip,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_FLUSH
+ gdisp_lld_flush,
+ #else
+ 0,
+ #endif
+ }};
+
+ //--------------------------------------------------------------------------------------------------------
+
+ /* Low level driver pixel format information */
+ //-------------------------
+ // True-Color color system
+ //-------------------------
+ #if GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
+
+ // Calculate the number of bits
+ #define LLDCOLOR_BITS_R ((GDISP_LLD_PIXELFORMAT>>8) & 0x0F)
+ #define LLDCOLOR_BITS_G ((GDISP_LLD_PIXELFORMAT>>4) & 0x0F)
+ #define LLDCOLOR_BITS_B ((GDISP_LLD_PIXELFORMAT>>0) & 0x0F)
+ #define LLDCOLOR_BITS (LLDCOLOR_BITS_R + LLDCOLOR_BITS_G + LLDCOLOR_BITS_B)
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if LLDCOLOR_BITS <= 8
+ #define LLDCOLOR_TYPE uint8_t
+ #define LLDCOLOR_TYPE_BITS 8
+ #elif LLDCOLOR_BITS <= 16
+ #define LLDCOLOR_TYPE uint16_t
+ #define LLDCOLOR_TYPE_BITS 16
+ #elif LLDCOLOR_BITS <= 32
+ #define LLDCOLOR_TYPE uint32_t
+ #define LLDCOLOR_TYPE_BITS 32
+ #else
+ #error "GDISP: Cannot define low level driver color types with more than 32 bits"
+ #endif
+ #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
+ #define LLDCOLOR_NEEDS_MASK FALSE
+ #else
+ #define LLDCOLOR_NEEDS_MASK TRUE
+ #endif
+ #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
+
+ // Calculate the component bit shifts
+ #if (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB
+ #define LLDCOLOR_SHIFT_R (LLDCOLOR_BITS_B+LLDCOLOR_BITS_G)
+ #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_B
+ #define LLDCOLOR_SHIFT_B 0
+ #else
+ #define LLDCOLOR_SHIFT_B (LLDCOLOR_BITS_R+LLDCOLOR_BITS_G)
+ #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_R
+ #define LLDCOLOR_SHIFT_R 0
+ #endif
+
+ // Calculate LLDRED_OF, LLDGREEN_OF, LLDBLUE_OF and LLDRGB2COLOR
+ #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 8
+ #define LLDRED_OF(c) ((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R))
+ #define LLDRGB2COLOR_R(r) ((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))))
+ #elif LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R > 8
+ #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) >> (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
+ #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
+ #else // LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R < 8
+ #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) << (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) >> (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #endif
+ #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 8
+ #define LLDGREEN_OF(c) ((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G))
+ #define LLDRGB2COLOR_G(g) ((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))))
+ #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 8
+ #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) >> (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
+ #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
+ #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 8
+ #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) << (8-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
+ #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) >> (8-(LLDCOLOR_BITS_LLDG+COLOR_SHIFT_G)))
+ #endif
+ #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
+ #define LLDBLUE_OF(c) ((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B))
+ #define LLDRGB2COLOR_B(b) ((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))))
+ #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
+ #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) >> (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #define LLDRGB2COLOR_B(b) (((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
+ #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) << (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #define LLDRGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #endif
+ #define LLDLUMA_OF(c) ((LLDRED_OF(c)+((uint16_t)LLDGREEN_OF(c)<<1)+LLDBLUE_OF(c))>>2)
+ #define LLDEXACT_RED_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_R)&((1<<LLDCOLOR_BITS_R)-1))*255)/((1<<LLDCOLOR_BITS_R)-1))
+ #define LLDEXACT_GREEN_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_G)&((1<<LLDCOLOR_BITS_G)-1))*255)/((1<<LLDCOLOR_BITS_G)-1))
+ #define LLDEXACT_BLUE_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_B)&((1<<LLDCOLOR_BITS_B)-1))*255)/((1<<LLDCOLOR_BITS_B)-1))
+ #define LLDEXACT_LUMA_OF(c) ((LLDEXACT_RED_OF(c)+((uint16_t)LLDEXACT_GREEN_OF(c)<<1)+LLDEXACT_BLUE_OF(c))>>2)
+ #define LLDLUMA2COLOR(l) (LLDRGB2COLOR_R(l) | LLDRGB2COLOR_G(l) | LLDRGB2COLOR_B(l))
+ #define LLDRGB2COLOR(r,g,b) (LLDRGB2COLOR_R(r) | LLDRGB2COLOR_G(g) | LLDRGB2COLOR_B(b))
+
+ // Calculate LLDHTML2COLOR
+ #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 24
+ #define LLDHTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16))
+ #elif COLOR_BITS_R + COLOR_SHIFT_R > 24
+ #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-24))
+ #else // COLOR_BITS_R + COLOR_SHIFT_R < 24
+ #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) >> (24-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #endif
+ #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 16
+ #define LLDHTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8))
+ #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 16
+ #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-16))
+ #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 16
+ #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) >> (16-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
+ #endif
+ #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
+ #define LLDHTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))
+ #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
+ #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
+ #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #endif
+ #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(LLDHTML2COLOR_R(h) | LLDHTML2COLOR_G(h) | LLDHTML2COLOR_B(h)))
+
+ //-------------------------
+ // Gray-scale color system
+ //-------------------------
+ #elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE
+
+ // Calculate the number of bits and shifts
+ #define LLDCOLOR_BITS (GDISP_LLD_PIXELFORMAT & 0xFF)
+ #define LLDCOLOR_BITS_R LLDCOLOR_BITS
+ #define LLDCOLOR_BITS_G LLDCOLOR_BITS
+ #define LLDCOLOR_BITS_B LLDCOLOR_BITS
+ #define LLDCOLOR_SHIFT_R 0
+ #define LLDCOLOR_SHIFT_G 0
+ #define LLDCOLOR_SHIFT_B 0
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if LLDCOLOR_BITS <= 8
+ #define LLDCOLOR_TYPE uint8_t
+ #define LLDCOLOR_TYPE_BITS 8
+ #else
+ #error "GDISP: Cannot define gray-scale low level driver color types with more than 8 bits"
+ #endif
+ #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
+ #define LLDCOLOR_NEEDS_MASK FALSE
+ #else
+ #define LLDCOLOR_NEEDS_MASK TRUE
+ #endif
+ #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
+
+ #if COLOR_BITS == 1
+ #define LLDRGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0)
+ #define LLDLUMA2COLOR(l) ((l) ? 1 : 0)
+ #define LLDHTML2COLOR(h) ((h) ? 1 : 0)
+ #define LLDLUMA_OF(c) ((c) ? 255 : 0)
+ #define LLDEXACT_LUMA_OF(c) LLDLUMA_OF(c)
+ #else
+ // They eye is more sensitive to green
+ #define LLDRGB2COLOR(r,g,b) ((LLDCOLOR_TYPE)(((uint16_t)(r)+(g)+(g)+(b)) >> (10-LLDCOLOR_BITS)))
+ #define LLDLUMA2COLOR(l) ((LLDCOLOR_TYPE)((l)>>(8-LLDCOLOR_BITS)))
+ #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-LLDCOLOR_BITS)))
+ #define LLDLUMA_OF(c) (((c) & ((1<<LLDCOLOR_BITS)-1)) << (8-LLDCOLOR_BITS))
+ #define LLDEXACT_LUMA_OF(c) ((((uint16_t)(c) & ((1<<LLDCOLOR_BITS)-1))*255)/((1<<LLDCOLOR_BITS)-1))
+ #endif
+
+ #define LLDRED_OF(c) LLDLUMA_OF(c)
+ #define LLDGREEN_OF(c) LLDLUMA_OF(c)
+ #define LLDBLUE_OF(c) LLDLUMA_OF(c)
+ #define LLDEXACT_RED_OF(c) LLDEXACT_LUMA_OF(c)
+ #define LLDEXACT_GREEN_OF(c) LLDEXACT_LUMA_OF(c)
+ #define LLDEXACT_BLUE_OF(c) LLDEXACT_LUMA_OF(c)
+
+ //-------------------------
+ // Palette color system
+ //-------------------------
+ #elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE
+
+ #error "GDISP: A palette color system for low level drivers is not currently supported"
+
+ //-------------------------
+ // Some other color system
+ //-------------------------
+ #else
+ #error "GDISP: Unsupported color system for low level drivers"
+ #endif
+
+ /* Which is the larger color type */
+ #if COLOR_BITS > LLDCOLOR_BITS
+ #define LARGER_COLOR_BITS COLOR_BITS
+ #define LARGER_COLOR_TYPE COLOR_TYPE
+ #else
+ #define LARGER_COLOR_BITS LLDCOLOR_BITS
+ #define LARGER_COLOR_TYPE LLDCOLOR_TYPE
+ #endif
+
+ /**
+ * @brief Controls color conversion accuracy for a low level driver
+ * @details Should higher precision be used when converting colors.
+ * @note Color conversion is only necessary if GDISP_PIXELFORMAT != GDISP_LLD_PIXELFORMAT
+ * @note It only makes sense to turn this on if you have a high bit depth display but
+ * are running the application in low bit depths.
+ * @note To achieve higher color accuracy bit shifting is replaced with multiplies and divides.
+ */
+ #ifndef GDISP_HARDWARE_USE_EXACT_COLOR
+ #if LLDCOLOR_BITS_R - COLOR_BITS_R >= LLDCOLOR_BITS_R/2 || LLDCOLOR_BITS_G - COLOR_BITS_G >= LLDCOLOR_BITS_G/2 || LLDCOLOR_BITS_B - COLOR_BITS_B >= LLDCOLOR_BITS_B/2
+ #define GDISP_HARDWARE_USE_EXACT_COLOR TRUE
+ #else
+ #define GDISP_HARDWARE_USE_EXACT_COLOR FALSE
+ #endif
+ #endif
+
+ /* Low level driver pixel format conversion functions */
+ #if GDISP_PIXELFORMAT == GDISP_LLD_PIXELFORMAT || defined(__DOXYGEN__)
+ /**
+ * @brief Convert from a standard color format to the low level driver pixel format
+ * @note For use only by low level drivers
+ */
+ #define gdispColor2Native(c) (c)
+ /**
+ * @brief Convert from a low level driver pixel format to the standard color format
+ * @note For use only by low level drivers
+ */
+ #define gdispNative2Color(c) (c)
+ #else
+ static LLDCOLOR_TYPE gdispColor2Native(color_t c) {
+ #if COLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE || LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE
+ #if GDISP_HARDWARE_USE_EXACT_COLOR
+ return LLDLUMA2COLOR(EXACT_LUMA_OF(c));
+ #else
+ return LLDLUMA2COLOR(LUMA_OF(c));
+ #endif
+ #elif COLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR && LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR
+ #if GDISP_HARDWARE_USE_EXACT_COLOR
+ return LLDRGB2COLOR(EXACT_RED_OF(c), EXACT_GREEN_OF(c), EXACT_BLUE_OF(c));
+ #else
+ return LLDRGB2COLOR(RED_OF(c), GREEN_OF(c), BLUE_OF(c));
+ #endif
+ #else
+ #error "GDISP: This pixel format conversion is not supported yet"
+ #endif
+ }
+ static color_t gdispNative2Color(LLDCOLOR_TYPE c) {
+ #if COLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE || LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE
+ #if GDISP_HARDWARE_USE_EXACT_COLOR
+ return LUMA2COLOR(LLDEXACT_LUMA_OF(c));
+ #else
+ return LUMA2COLOR(LLDLUMA_OF(c));
+ #endif
+ #elif COLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR && LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR
+ #if GDISP_HARDWARE_USE_EXACT_COLOR
+ return RGB2COLOR(LLDEXACT_RED_OF(c), LLDEXACT_GREEN_OF(c), LLDEXACT_BLUE_OF(c));
+ #else
+ return RGB2COLOR(LLDRED_OF(c), LLDGREEN_OF(c), LLDBLUE_OF(c));
+ #endif
+ #else
+ #error "GDISP: This pixel format conversion is not supported yet"
+ #endif
+ }
+ #endif
+
+#endif
+
+//------------------------------------------------------------------------------------------------------------
+
+#undef IN_PIXMAP_DRIVER
+#undef IS_MULTIPLE
+#undef IN_DRIVER
+#undef USE_VMT
+#endif /* GFX_USE_GDISP */
+
+#endif /* _GDISP_LLD_H */
+/** @} */