5 changed files with 366 additions and 0 deletions
@ -0,0 +1,30 @@ |
|||
/*
|
|||
* 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
|
|||
*/ |
|||
|
|||
#define SCREEN_WIDTH 800 |
|||
#define SCREEN_HEIGHT 480 |
|||
#define FRAMEREADER_BASE ALT_VIP_VFR_0_BASE |
|||
|
|||
#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 |
@ -0,0 +1,2 @@ |
|||
GFXINC += $(GFXLIB)/drivers/gdisp/AlteraFramereader |
|||
GFXSRC += $(GFXLIB)/drivers/gdisp/AlteraFramereader/gdisp_lld_alteraframereader.c |
@ -0,0 +1,280 @@ |
|||
/*
|
|||
* 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 <system.h> |
|||
#include <io.h> |
|||
#include <string.h> |
|||
#include "gfx.h" |
|||
|
|||
#if GFX_USE_GDISP |
|||
|
|||
#define GDISP_DRIVER_VMT GDISPVMT_alteraframereader |
|||
#include "gdisp_lld_config.h" |
|||
#include "../../../src/gdisp/gdisp_driver.h" |
|||
#include "board_alteraframereader.h" |
|||
|
|||
#ifndef FRAMEREADER_BASE |
|||
#error "Framereader IP base address (FRAMEREADER_BASE) not set in board file." |
|||
#endif |
|||
#ifndef SCREEN_WIDTH |
|||
#error "Screen width (SCREEN_WIDTH) not set in board file." |
|||
#endif |
|||
#ifndef SCREEN_HEIGHT |
|||
#error "Screen height (SCREEN_HEIGHT) not set in board file." |
|||
#endif |
|||
|
|||
// ToDo: Merge this into fbPriv
|
|||
typedef struct fbInfo { |
|||
void* pixels; // The pixel buffer
|
|||
coord_t linelen; // The number of bytes per display line
|
|||
} fbInfo; |
|||
|
|||
typedef struct fbPriv { |
|||
fbInfo fbi; // Display information
|
|||
void* frame0; |
|||
void* frame1; |
|||
} 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)) |
|||
#define PRIV(g) ((fbPriv *)g->priv) |
|||
|
|||
/*===========================================================================*/ |
|||
/* Driver exported functions. */ |
|||
/*===========================================================================*/ |
|||
|
|||
LLDSPEC bool_t gdisp_lld_init(GDisplay* g) |
|||
{ |
|||
// Allocate the frame buffers
|
|||
PRIV(g)->frame0 = gfxAlloc(SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(LLDCOLOR_TYPE)); |
|||
PRIV(g)->frame1 = gfxAlloc(SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(LLDCOLOR_TYPE)); |
|||
if (!PRIV(g)->frame0 || !PRIV(g)->frame1) { |
|||
gfxHalt("Couldn't allocate memory for framebuffer\r\n"); |
|||
} |
|||
|
|||
// Initialize the private structure
|
|||
g->g.Width = SCREEN_WIDTH; |
|||
g->g.Height = SCREEN_HEIGHT; |
|||
g->g.Backlight = 100; |
|||
g->g.Contrast = 50; |
|||
g->g.Orientation = GDISP_ROTATE_0; |
|||
g->g.Powermode = powerOn; |
|||
g->board = 0; |
|||
PRIV(g)->fbi.linelen = g->g.Width * sizeof(LLDCOLOR_TYPE); // bytes per line
|
|||
PRIV(g)->fbi.pixels = PRIV(g)->frame0; |
|||
|
|||
// Make sure the MSB is set so we bypass the data cache of the NIOS-II soft core
|
|||
PRIV(g)->fbi.pixels = (void*)((char*)PRIV(g)->fbi.pixels + 0x80000000); |
|||
|
|||
// Stop the framereader to allow for configuration
|
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x00, 0x00); // stop for config
|
|||
|
|||
// Frame 0
|
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x04, (uint32_t)PRIV(g)->frame0); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x05, SCREEN_WIDTH*SCREEN_HEIGHT/2); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x06, SCREEN_WIDTH*SCREEN_HEIGHT); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x08, SCREEN_WIDTH); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x09, SCREEN_HEIGHT); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x0a, 0x00); |
|||
|
|||
// Frame 1
|
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x0b, (uint32_t)PRIV(g)->frame1); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x0c, SCREEN_WIDTH*SCREEN_HEIGHT/2); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x0d, SCREEN_WIDTH*SCREEN_HEIGHT); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x0f, SCREEN_WIDTH); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x10, SCREEN_HEIGHT); |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x11, 0x00); |
|||
|
|||
// Select frame0 (user draws to frame0 -> double buffering disabled by default)
|
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x03, 0x00); |
|||
|
|||
// Start the framebuffer reader
|
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x00, 0x01); |
|||
|
|||
return TRUE; |
|||
} |
|||
|
|||
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; |
|||
|
|||
case GDISP_CONTROL_BUFFERS_SWAP: |
|||
if (PRIV(g)->fbi.pixels == PRIV(g)->frame0) { |
|||
PRIV(g)->fbi.pixels = PRIV(g)->frame1; |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x03, 0x00); |
|||
} else { |
|||
PRIV(g)->fbi.pixels = PRIV(g)->frame0; |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x03, 0x01); |
|||
} |
|||
return; |
|||
|
|||
case GDISP_CONTROL_BUFFERS_ENABLE: |
|||
// Display frame0, draw to frame1
|
|||
PRIV(g)->fbi.pixels = PRIV(g)->frame1; |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x03, 0x00); |
|||
return; |
|||
|
|||
case GDISP_CONTROL_BUFFERS_DISABLE: |
|||
// Display frame0, draw to frame0
|
|||
PRIV(g)->fbi.pixels = PRIV(g)->frame0; |
|||
IOWR(ALT_VIP_VFR_0_BASE, 0x03, 0x00); |
|||
return; |
|||
} |
|||
} |
|||
#endif |
|||
|
|||
#if GDISP_HARDWARE_FILLS |
|||
LLDSPEC void gdisp_lld_fill_area(GDisplay* g) |
|||
{ |
|||
int i; |
|||
unsigned int addr; |
|||
int bytes_per_line; |
|||
int bytes_per_pixel; |
|||
uint8_t* line; |
|||
|
|||
// Calculate some values required for further calculations
|
|||
bytes_per_pixel = ((fbPriv*)g->priv)->fbi.linelen/g->g.Width; // must be 4
|
|||
bytes_per_line = ((fbPriv*)g->priv)->fbi.linelen; |
|||
|
|||
// Allocate line buffer
|
|||
line = gfxAlloc(bytes_per_pixel * g->p.cx); |
|||
|
|||
// Fill the line buffer with the solid color
|
|||
for (i = 0; i < bytes_per_pixel * g->p.cx; i += 4) { |
|||
*((color_t*)(line + i)) = g->p.color; |
|||
} |
|||
|
|||
// Calculate the address of the first pixel of the rectangle (top left corner)
|
|||
addr = (int)((char *)((fbPriv *)g->priv)->fbi.pixels + (g->p.y * bytes_per_line) + (g->p.x * bytes_per_pixel)); |
|||
|
|||
// Copy filled line buffer to create rectangle
|
|||
for (i = 0; i < g->p.cy; i++) { |
|||
memcpy((void*)addr, line, bytes_per_pixel * g->p.cx); |
|||
addr += bytes_per_line; |
|||
} |
|||
|
|||
// Free the line buffer
|
|||
gfxFree(line); |
|||
} |
|||
#endif // GDISP_HARDWARE_FILLS
|
|||
|
|||
#endif /* GFX_USE_GDISP */ |
@ -0,0 +1,27 @@ |
|||
/*
|
|||
* 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 |
|||
|
|||
#define GDISP_HARDWARE_DRAWPIXEL TRUE |
|||
#define GDISP_HARDWARE_PIXELREAD TRUE |
|||
#define GDISP_HARDWARE_CONTROL TRUE |
|||
#define GDISP_HARDWARE_FILLS TRUE |
|||
|
|||
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 |
|||
|
|||
// gdispControl() options
|
|||
#define GDISP_CONTROL_BUFFERS_SWAP (GDISP_CONTROL_LLD+0) // Swap framebuffers (double buffering). Parameter is ignored.
|
|||
#define GDISP_CONTROL_BUFFERS_ENABLE (GDISP_CONTROL_LLD+1) // Enable double buffering. Parameter is ignored.
|
|||
#define GDISP_CONTROL_BUFFERS_DISABLE (GDISP_CONTROL_LLD+2) // Disable double buffering. Parameter is ignored.
|
|||
|
|||
#endif /* GFX_USE_GDISP */ |
|||
|
|||
#endif /* _GDISP_LLD_CONFIG_H */ |
@ -0,0 +1,27 @@ |
|||
This driver can be used for the "Frame Reader IP Core" that comes with the "Video and Image Processing Suite" package |
|||
from Altera/Intel/Quartus. |
|||
|
|||
This driver takes advantage of the double buffering feature offered by the "Frame Reader IP Core". The following commands |
|||
can be used through the gdispControl() API to manage the two frame buffers: |
|||
|
|||
gdispControl(GDISP_CONTROL_BUFFERS_ENABLE, 0); // Enabel the two framebuffers (Disabled by default) |
|||
gdispControl(GDISP_CONTROL_BUFFERS_DISABLE, 0); // Disable the two framebuffers (Disabled by default) |
|||
gdispControl(GDISP_CONTROL_BUFFERS_SWAP, 0); // Swap the framebuffers (if enabled) |
|||
|
|||
The double buffering is taken care of completely by the driver. It sets the framebuffer pointers correctly so that it's |
|||
transparent to the application. There's no need to handle the two framebuffers manually through the multiple displays |
|||
support offered by uGFX. Using GDISP_CONTROL_BUFFERS_SWAP will swap the framebuffers on the actual hardware as well |
|||
as swap the framebuffer pointers for the default GDisplay to draw to the other framebuffer. |
|||
|
|||
|
|||
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/AlteraFramereader/driver.mk |
|||
|
|||
3. Add a board_alteraframereader.h to you project directory (or board directory) |
|||
base on one of the templates found in this drivers directory. |
Loading…
Reference in new issue