From 285bd0f4d66fa3161a80bf6711d1bef226b17fe3 Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 22 May 2014 17:21:19 +1000 Subject: [PATCH] GDISP framebuffer driver + an implementation for the linux kernel framebuffer device --- boards/base/Linux-Framebuffer/board.mk | 5 + .../Linux-Framebuffer/board_framebuffer.h | 217 ++++++++++++++++++ .../base/Linux-Framebuffer/example/Makefile | 155 +++++++++++++ .../base/Linux-Framebuffer/example/readme.txt | 5 + boards/base/Linux-Framebuffer/readme.txt | 6 + boards/base/Linux/readme.txt | 4 +- docs/releases.txt | 3 +- .../framebuffer/board_framebuffer_template.h | 57 +++++ drivers/gdisp/framebuffer/driver.mk | 2 + drivers/gdisp/framebuffer/gdisp_lld_config.h | 38 +++ .../gdisp/framebuffer/gdisp_lld_framebuffer.c | 175 ++++++++++++++ drivers/gdisp/framebuffer/readme.txt | 11 + 12 files changed, 674 insertions(+), 4 deletions(-) create mode 100644 boards/base/Linux-Framebuffer/board.mk create mode 100644 boards/base/Linux-Framebuffer/board_framebuffer.h create mode 100644 boards/base/Linux-Framebuffer/example/Makefile create mode 100644 boards/base/Linux-Framebuffer/example/readme.txt create mode 100644 boards/base/Linux-Framebuffer/readme.txt create mode 100644 drivers/gdisp/framebuffer/board_framebuffer_template.h create mode 100644 drivers/gdisp/framebuffer/driver.mk create mode 100644 drivers/gdisp/framebuffer/gdisp_lld_config.h create mode 100644 drivers/gdisp/framebuffer/gdisp_lld_framebuffer.c create mode 100644 drivers/gdisp/framebuffer/readme.txt diff --git a/boards/base/Linux-Framebuffer/board.mk b/boards/base/Linux-Framebuffer/board.mk new file mode 100644 index 00000000..69be7ac1 --- /dev/null +++ b/boards/base/Linux-Framebuffer/board.mk @@ -0,0 +1,5 @@ +GFXINC += $(GFXLIB)/boards/base/Linux-Framebuffer +GFXSRC += +GFXDEFS += -DGFX_USE_OS_LINUX=TRUE + +include $(GFXLIB)/drivers/gdisp/framebuffer/driver.mk diff --git a/boards/base/Linux-Framebuffer/board_framebuffer.h b/boards/base/Linux-Framebuffer/board_framebuffer.h new file mode 100644 index 00000000..71e00937 --- /dev/null +++ b/boards/base/Linux-Framebuffer/board_framebuffer.h @@ -0,0 +1,217 @@ +/* + * 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 + */ + +// Set this to your frame buffer pixel format. Note Linux frame buffer only supports RGB modes (no BGR modes). +#ifndef GDISP_LLD_PIXELFORMAT + #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 +#endif + +#ifdef GDISP_DRIVER_VMT + + #define FBDEV_PATH1 "/dev/fb0" + #define FBDEV_PATH2 "/dev/fb/0" // Optional - comment this out to only try the one device + #define USE_SET_MODE // Optional - comment this out to not to try to set the color mode we want + //#define VTDEV_PATH "/dev/tty0" // Optional - if defined use this tty to switch from text to graphics mode + + #define _GNU_SOURCE 1 + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #if VTDEV_PATH + static void board_revert2textmode(void) { + int tty; + + // Go back to text mode + if ((tty = open(VTDEV_PATH, O_RDWR)) >= 0) { + ioctl(tty, KDSETMODE, KD_TEXT); + close(tty); + } + } + static void board_switch2graphicsmode(void) { + int tty; + + // Open the tty + if ((tty = open (VTDEV_PATH, O_RDWR)) < 0) { + fprintf(stderr, "GDISP Framebuffer: Cannot open tty %s\n", VTDEV_PATH); + exit(-1); + } + if (ioctl (tty, KDSETMODE, KD_GRAPHICS) == -1) { + fprintf(stderr, "GDISP Framebuffer: Cannot set to graphics mode\n"); + exit(-1); + } + close(tty); + + // Make sure we clean up properly + atexit(board_revert2textmode) + } + #endif + + static void board_init(GDisplay *g, fbInfo *fbi) { + int fb; + char * env; + size_t fblen; + struct fb_fix_screeninfo fb_fix; + struct fb_var_screeninfo fb_var; + + // Open the frame buffer device + if((env = getenv("FRAMEBUFFER")) != 0) + fb = open(env, O_RDWR); + else { + fb = open(FBDEV_PATH1, O_RDWR); + #ifdef FBDEV_PATH2 + if (fb < 0) fb = open(FBDEV_PATH2, O_RDWR); + #endif + } + if(fb < 0) { + fprintf(stderr, "GDISP Framebuffer: Error opening the framebuffer device\n"); + exit(-1); + } + + // Get screen info + if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) == -1 || ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) { + fprintf(stderr, "GDISP Framebuffer: Error getting screen info\n"); + exit(-1); + } + + #ifdef USE_SET_MODE + info.reserved[0] = 0; + fb_var.reserved[1] = 0; + fb_var.reserved[2] = 0; + fb_var.xoffset = 0; + fb_var.yoffset = 0; + fb_var.bits_per_pixel = LLDCOLOR_BITS; + fb_var.activate = FB_ACTIVATE_NOW; + if (ioctl(fb, FBIOPUT_VSCREENINFO, &fb_var) == -1 || ioctl (fb, FBIOGET_VSCREENINFO, &fb_var) == -1) { + fprintf(stderr, "GDISP Framebuffer: Failed to set video mode\n"); + exit(-1); + } + #endif + + // Check things are as they should be + if (fb_fix.type != FB_TYPE_PACKED_PIXELS) { + fprintf(stderr, "GDISP Framebuffer: The display is not in a single plane graphics mode\n"); + exit(-1); + } + if (fb_fix.visual != FB_VISUAL_TRUECOLOR) { + fprintf(stderr, "GDISP Framebuffer: The display is not in TRUECOLOR mode\n"); + exit(-1); + } + if (fb_var.bits_per_pixel != LLDCOLOR_BITS) { + fprintf(stderr, "GDISP Framebuffer: The display is not %u bits per pixel\n", LLDCOLOR_BITS); + exit(-1); + } + if (fb_var.red.length != LLDCOLOR_BITS_R || fb_var.green.length != LLDCOLOR_BITS_G || fb_var.blue.length != LLDCOLOR_BITS_B) { + fprintf(stderr, "GDISP Framebuffer: The display pixel format is not %d%d%d\n", LLDCOLOR_BITS_R, LLDCOLOR_BITS_G, LLDCOLOR_BITS_B); + exit(-1); + } + if (fb_var.red.offset != LLDCOLOR_SHIFT_R || fb_var.green.offset != LLDCOLOR_SHIFT_G || fb_var.blue.offset != LLDCOLOR_SHIFT_B) { + #if LLDCOLOR_SHIFT_B == 0 + fprintf(stderr, "GDISP Framebuffer: THe display pixel format is not RGB\n"); + #else + fprintf(stderr, "GDISP Framebuffer: The display pixel format is not BGR\n"); + #endif + exit(-1); + } + + // Ensure we are at the origin of the virtual display area + if (fb_var.xoffset || fb_var.yoffset) { + fb_var.xoffset = 0; + fb_var.yoffset = 0; + ioctl(fb, FBIOPAN_DISPLAY, &fb_var); + } + + // Switch to graphics mode (if required) + #ifdef VTDEV_PATH + board_switch2graphicsmode(); + #endif + + // Calculate the frame buffer length + fblen = fb_var.yres * fb_fix.line_length; + + // Different systems need mapping in slightly different ways - Yuck! + #ifdef ARCH_LINUX_SPARC + #define CG3_MMAP_OFFSET 0x4000000 + #define CG6_RAM 0x70016000 + #define TCX_RAM8BIT 0x00000000 + #define TCX_RAM24BIT 0x01000000 + switch (fb_fix.accel) { + case FB_ACCEL_SUN_CGTHREE: + fbi->pixels = mmap(0, fblen, PROT_READ|PROT_WRITE, MAP_SHARED, fb, CG3_MMAP_OFFSET); + break; + case FB_ACCEL_SUN_CGSIX: + fbi->pixels = mmap(0, fblen, PROT_READ|PROT_WRITE, MAP_SHARED, fb, CG6_RAM); + break; + case FB_ACCEL_SUN_TCX: + fbi->pixels = mmap(0, fblen, PROT_READ|PROT_WRITE, MAP_SHARED, fb, TCX_RAM24BIT); + break; + default: + fprintf(stderr, "GDISP Framebuffer: Don't know how to mmap with accel %d\n", fb_fix.accel); + exit(-1); + } + #elif defined(BLACKFIN) + fbi->pixels = mmap(0, fblen, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FILE, fb, 0); + #elif defined(__uClinux__) + fbi->pixels = mmap(0, fblen, PROT_READ|PROT_WRITE, 0, fb, 0); + #else + fbi->pixels = mmap(0, fblen, PROT_READ|PROT_WRITE, MAP_SHARED, fb, 0); + #endif + if(!fbi->pixels || fbi->pixels == (void *)-1) { + fprintf(stderr, "GDISP Framebuffer: mmap of display buffer failed\n"); + exit(-1); + } + + // If this program gets children they should not inherit this file descriptor + fcntl(fb, F_SETFD, FD_CLOEXEC); + + // We are finished with the file descriptor + close(fb); + + // Set the rest of the details of the frame buffer + g->g.Width = fb_var.xres; + g->g.Height = fb_var.yres; + g->g.Backlight = 100; + g->g.Contrast = 50; + fbi->linelen = fb_fix.line_length; + } + + #if GDISP_HARDWARE_FLUSH + static void board_flush(GDisplay *g) { + (void) g; + } + #endif + + #if GDISP_NEED_CONTROL + static void board_backlight(GDisplay *g, uint8_t percent) { + (void) g; + (void) percent; + } + + static void board_contrast(GDisplay *g, uint8_t percent) { + (void) g; + (void) percent; + } + + static void board_power(GDisplay *g, powermode_t pwr) { + (void) g; + (void) pwr; + } + #endif + +#endif /* GDISP_LLD_BOARD_IMPLEMENTATION */ diff --git a/boards/base/Linux-Framebuffer/example/Makefile b/boards/base/Linux-Framebuffer/example/Makefile new file mode 100644 index 00000000..66af4bdc --- /dev/null +++ b/boards/base/Linux-Framebuffer/example/Makefile @@ -0,0 +1,155 @@ +# +# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! +# +############################################################################################## +# +# On command line: +# +# make all = Create project +# +# make clean = Clean project files. +# +# To rebuild project do "make clean" and "make all". +# + +############################################################################################## +# Start of default section +# + +TRGT = +CC = $(TRGT)gcc +AS = $(TRGT)gcc -x assembler-with-cpp + +# List all default C defines here, like -D_DEBUG=1 +DDEFS = + +# List all default ASM defines here, like -D_DEBUG=1 +DADEFS = + +# List all default directories to look for include files here +DINCDIR = + +# List the default directory to look for the libraries here +DLIBDIR = + +# List all default libraries here +DLIBS = -lX11 -pthread -lrt + +# +# End of default section +############################################################################################## + +############################################################################################## +# Start of user section +# + +# Define project name here +PROJECT = ugfx + +# Imported source files and paths for uGFX +GFXLIB = ../ugfx +include ${GFXLIB}/gfx.mk +include ${GFXLIB}/boards/base/Linux-Framebuffer/board.mk + +# Where is our source code - alter these for your project. +# Either just include the demo makefile or add your own definitions +include $(GFXLIB)/demos/modules/gdisp/basics/demo.mk +#MYFILES = my-project-directory +#MYCSRC = $(MYFILES)/main.c +#MYDEFS = + +# List all user C define here, like -D_DEBUG=1 +UDEFS = $(MYDEFS) $(GFXDEFS) + +# Define ASM defines here +UADEFS = + +# List C source files here +SRC = $(GFXSRC) \ + $(MYCSRC) + +# List ASM source files here +ASRC = + +# List all user directories here +UINCDIR = $(MYFILES) $(GFXINC) + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# Define optimisation level here +OPT = -ggdb -O0 -fomit-frame-pointer + +# +# End of user defines +############################################################################################## + +INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) +LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) +DEFS = $(DDEFS) $(UDEFS) +ADEFS = $(DADEFS) $(UADEFS) +OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) +LIBS = $(DLIBS) $(ULIBS) + +ASFLAGS = -Wa,-amhls=$(<:.s=.lst) $(ADEFS) +CPFLAGS = $(OPT) -Wall -Wextra -Wstrict-prototypes -fverbose-asm $(DEFS) + +ifeq ($(HOST_OSX),yes) + ifeq ($(OSX_SDK),) + OSX_SDK = /Developer/SDKs/MacOSX10.7.sdk + endif + ifeq ($(OSX_ARCH),) + OSX_ARCH = -mmacosx-version-min=10.3 -arch i386 + endif + + CPFLAGS += -isysroot $(OSX_SDK) $(OSX_ARCH) + LDFLAGS = -Wl -Map=$(PROJECT).map,-syslibroot,$(OSX_SDK),$(LIBDIR) + LIBS += $(OSX_ARCH) +else + # Linux, or other + CPFLAGS += -m32 -Wa,-alms=$(<:.c=.lst) + LDFLAGS = -m32 -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR) +endif + +# Generate dependency information +CPFLAGS += -MD -MP -MF .dep/$(@F).d + +# +# makefile rules +# + +all: $(OBJS) $(PROJECT) + +%.o : %.c + $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ + +%.o : %.s + $(AS) -c $(ASFLAGS) $< -o $@ + +$(PROJECT): $(OBJS) + $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ + +gcov: + -mkdir gcov + $(COV) -u $(subst /,\,$(SRC)) + -mv *.gcov ./gcov + +clean: + -rm -f $(OBJS) + -rm -f $(PROJECT) + -rm -f $(PROJECT).map + -rm -f $(SRC:.c=.c.bak) + -rm -f $(SRC:.c=.lst) + -rm -f $(ASRC:.s=.s.bak) + -rm -f $(ASRC:.s=.lst) + -rm -fR .dep + +# +# Include the dependency files, should be the last of the makefile +# +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# *** EOF *** diff --git a/boards/base/Linux-Framebuffer/example/readme.txt b/boards/base/Linux-Framebuffer/example/readme.txt new file mode 100644 index 00000000..aff58bb1 --- /dev/null +++ b/boards/base/Linux-Framebuffer/example/readme.txt @@ -0,0 +1,5 @@ +Copy these files into your own project directory and alter them to suite. + +Notes: + +1/ Look at the MYFILES definition and the MYCSRC definition. diff --git a/boards/base/Linux-Framebuffer/readme.txt b/boards/base/Linux-Framebuffer/readme.txt new file mode 100644 index 00000000..ede34281 --- /dev/null +++ b/boards/base/Linux-Framebuffer/readme.txt @@ -0,0 +1,6 @@ +This directory contains the interface for Linux using a framebuffer display. + +On this board uGFX currently supports: + - GDISP via the framebuffer driver + +There is an example Makefile and project in the examples directory. diff --git a/boards/base/Linux/readme.txt b/boards/base/Linux/readme.txt index 1557ebdd..b0d1dc1d 100644 --- a/boards/base/Linux/readme.txt +++ b/boards/base/Linux/readme.txt @@ -1,9 +1,7 @@ -This directory contains the interface for Linux -running either native Linux. +This directory contains the interface for Linux using X. On this board uGFX currently supports: - GDISP via the X driver - GINPUT-touch via the X driver There is an example Makefile and project in the examples directory. - diff --git a/docs/releases.txt b/docs/releases.txt index 757ff41d..77f98802 100644 --- a/docs/releases.txt +++ b/docs/releases.txt @@ -5,7 +5,8 @@ *** Changes After 2.1 *** FEATURE: Added nested containers demo FEATURE: Revised GWIN redraw strategy - +FEATURE: Added generic framebuffer driver +FEATURE: Added Linux-Framebuffer board definition *** Release 2.1 *** FIX: Significant improvements to the way the MCU touch driver works. diff --git a/drivers/gdisp/framebuffer/board_framebuffer_template.h b/drivers/gdisp/framebuffer/board_framebuffer_template.h new file mode 100644 index 00000000..0ee08ef2 --- /dev/null +++ b/drivers/gdisp/framebuffer/board_framebuffer_template.h @@ -0,0 +1,57 @@ +/* + * 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 + */ + +// Set this to your frame buffer pixel format. +#ifndef GDISP_LLD_PIXELFORMAT + #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_BGR888 +#endif + +// Uncomment this if your frame buffer device requires flushing +//#define GDISP_HARDWARE_FLUSH TRUE + +#ifdef GDISP_DRIVER_VMT + + static void board_init(GDisplay *g, fbInfo *fbi) { + // TODO: Initialize your frame buffer device here + + // TODO: Set the details of the frame buffer + g->g.Width = 640; + g->g.Height = 480; + g->g.Backlight = 100; + g->g.Contrast = 50; + fbi->linelen = g->g.Width * sizeof(LLDCOLOR_TYPE); // bytes per row + fbi->pixels = 0; // pointer to the memory frame buffer + } + + #if GDISP_HARDWARE_FLUSH + static void board_flush(GDisplay *g) { + // TODO: Can be an empty function if your hardware doesn't support this + (void) g; + } + #endif + + #if GDISP_NEED_CONTROL + static void board_backlight(GDisplay *g, uint8_t percent) { + // TODO: Can be an empty function if your hardware doesn't support this + (void) g; + (void) percent; + } + + static void board_contrast(GDisplay *g, uint8_t percent) { + // TODO: Can be an empty function if your hardware doesn't support this + (void) g; + (void) percent; + } + + static void board_power(GDisplay *g, powermode_t pwr) { + // TODO: Can be an empty function if your hardware doesn't support this + (void) g; + (void) pwr; + } + #endif + +#endif /* GDISP_LLD_BOARD_IMPLEMENTATION */ diff --git a/drivers/gdisp/framebuffer/driver.mk b/drivers/gdisp/framebuffer/driver.mk new file mode 100644 index 00000000..6b473c72 --- /dev/null +++ b/drivers/gdisp/framebuffer/driver.mk @@ -0,0 +1,2 @@ +GFXINC += $(GFXLIB)/drivers/gdisp/framebuffer +GFXSRC += $(GFXLIB)/drivers/gdisp/framebuffer/gdisp_lld_framebuffer.c diff --git a/drivers/gdisp/framebuffer/gdisp_lld_config.h b/drivers/gdisp/framebuffer/gdisp_lld_config.h new file mode 100644 index 00000000..08dbbb39 --- /dev/null +++ b/drivers/gdisp/framebuffer/gdisp_lld_config.h @@ -0,0 +1,38 @@ +/* + * 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 + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_CONTROL TRUE + +// Any other support comes from the board file +#include "board_framebuffer.h" + +#ifndef GDISP_LLD_PIXELFORMAT + #error "GDISP FrameBuffer: You must specify a GDISP_LLD_PIXELFORMAT in your board_framebuffer.h or your makefile" +#endif + +// This driver currently only supports unpacked formats with more than 8 bits per pixel +// that is, we only support GRAY_SCALE with 8 bits per pixel or any unpacked TRUE_COLOR format. +// Note: At the time this file is included we have not calculated all our color +// definitions so we need to do this by hand. +#if (GDISP_LLD_PIXELFORMAT & 0x4000) && (GDISP_LLD_PIXELFORMAT & 0xFF) != 8 + #error "GDISP FrameBuffer: This driver does not support the specified GDISP_LLD_PIXELFORMAT" +#endif + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/drivers/gdisp/framebuffer/gdisp_lld_framebuffer.c b/drivers/gdisp/framebuffer/gdisp_lld_framebuffer.c new file mode 100644 index 00000000..6e38b5f4 --- /dev/null +++ b/drivers/gdisp/framebuffer/gdisp_lld_framebuffer.c @@ -0,0 +1,175 @@ +/* + * 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 + */ + +#include "gfx.h" + +#if GFX_USE_GDISP + +typedef struct fbInfo { + void * pixels; // The pixel buffer + coord_t linelen; // The number of bytes per display line + } fbInfo; + +#define GDISP_DRIVER_VMT GDISPVMT_framebuffer +#include "drivers/gdisp/framebuffer/gdisp_lld_config.h" +#include "src/gdisp/driver.h" +#include "board_framebuffer.h" + +typedef struct fbPriv { + fbInfo fbi; // Display information + } fbPriv; + +/*===========================================================================*/ +/* Driver local routines . */ +/*===========================================================================*/ + +#define PIXIL_POS(g, x, y) ((y) * ((fbPriv *)(g)->priv)->fbi.linelen + (x) * sizeof(LLDCOLOR_TYPE)) +#define PIXEL_ADDR(g, pos) ((LLDCOLOR_TYPE *)(((char *)((fbPriv *)(g)->priv)->fbi.pixels)+pos)) + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { + + // Initialize the private structure + if (!(g->priv = gfxAlloc(sizeof(fbPriv)))) + gfxHalt("GDISP Framebuffer: Failed to allocate private memory"); + ((fbPriv *)g->priv)->fbi.pixels = 0; + ((fbPriv *)g->priv)->fbi.linelen = 0; + + // Initialize the GDISP structure + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->board = 0; // preinitialize + board_init(g, &((fbPriv *)g->priv)->fbi); + + return TRUE; +} + +#if GDISP_HARDWARE_FLUSH + LLDSPEC void gdisp_lld_flush(GDisplay *g) { + board_flush(g); + } +#endif + +LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + unsigned pos; + + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + default: + pos = PIXIL_POS(g, g->p.x, g->p.y); + break; + case GDISP_ROTATE_90: + pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-1); + break; + case GDISP_ROTATE_180: + pos = PIXIL_POS(g, g->g.Width-g->p.x-1, g->g.Height-g->p.y-1); + break; + case GDISP_ROTATE_270: + pos = PIXIL_POS(g, g->g.Height-g->p.y-1, g->p.x); + break; + } + #else + pos = PIXIL_POS(g, g->p.x, g->p.y); + #endif + + PIXEL_ADDR(g, pos)[0] = gdispColor2Native(g->p.color); +} + +LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { + unsigned pos; + LLDCOLOR_TYPE color; + + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + default: + pos = PIXIL_POS(g, g->p.x, g->p.y); + break; + case GDISP_ROTATE_90: + pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-1); + break; + case GDISP_ROTATE_180: + pos = PIXIL_POS(g, g->g.Width-g->p.x-1, g->g.Height-g->p.y-1); + break; + case GDISP_ROTATE_270: + pos = PIXIL_POS(g, g->g.Height-g->p.y-1, g->p.x); + break; + } + #else + pos = PIXIL_POS(g, g->p.x, g->p.y); + #endif + + color = PIXEL_ADDR(g, pos)[0]; + return gdispNative2Color(color); +} + +#if GDISP_NEED_CONTROL + LLDSPEC void gdisp_lld_control(GDisplay *g) { + switch(g->p.x) { + case GDISP_CONTROL_POWER: + if (g->g.Powermode == (powermode_t)g->p.ptr) + return; + switch((powermode_t)g->p.ptr) { + case powerOff: case powerOn: case powerSleep: case powerDeepSleep: + board_power(g, (powermode_t)g->p.ptr); + break; + default: + return; + } + g->g.Powermode = (powermode_t)g->p.ptr; + return; + + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + switch((orientation_t)g->p.ptr) { + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) { + coord_t tmp; + + tmp = g->g.Width; + g->g.Width = g->g.Height; + g->g.Height = tmp; + } + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + if (g->g.Orientation == GDISP_ROTATE_0 || g->g.Orientation == GDISP_ROTATE_180) { + coord_t tmp; + + tmp = g->g.Width; + g->g.Width = g->g.Height; + g->g.Height = tmp; + } + break; + default: + return; + } + g->g.Orientation = (orientation_t)g->p.ptr; + return; + + case GDISP_CONTROL_BACKLIGHT: + if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; + board_backlight(g, (unsigned)g->p.ptr); + g->g.Backlight = (unsigned)g->p.ptr; + return; + + case GDISP_CONTROL_CONTRAST: + if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; + board_contrast(g, (unsigned)g->p.ptr); + g->g.Contrast = (unsigned)g->p.ptr; + return; + } + } +#endif + +#endif /* GFX_USE_GDISP */ diff --git a/drivers/gdisp/framebuffer/readme.txt b/drivers/gdisp/framebuffer/readme.txt new file mode 100644 index 00000000..d07b5dfb --- /dev/null +++ b/drivers/gdisp/framebuffer/readme.txt @@ -0,0 +1,11 @@ +To use this driver: + +1. Add in your gfxconf.h: + a) #define GFX_USE_GDISP TRUE + +2. To your makefile add the following lines: + include $(GFXLIB)/gfx.mk + include $(GFXLIB)/drivers/gdisp/framebuffer/driver.mk + +3. Add a board_framebuffer.h to you project directory (or board directory) + base on one of the templates.