Convert ST7565 driver to new driver format.

ugfx_release_2.6
inmarket 2013-10-22 19:53:39 +10:00
parent 299cb353af
commit 92b00e125c
5 changed files with 320 additions and 306 deletions

View File

@ -0,0 +1,108 @@
/*
* 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 drivers/gdisp/ST7565/board_ST7565_template.h
* @brief GDISP Graphic Driver subsystem board interface for the ST7565 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
/**
* @brief Initialise the board for the display.
*
* @param[in] g The GDisplay structure
*
* @note Set the g->board member to whatever is appropriate. For multiple
* displays this might be a pointer to the appropriate register set.
*
* @notapi
*/
static inline void init_board(GDisplay *g) {
(void) g;
}
/**
* @brief After the initialisation.
*
* @param[in] g The GDisplay structure
*
* @notapi
*/
static inline void post_init_board(GDisplay *g) {
(void) g;
}
/**
* @brief Set or clear the lcd reset pin.
*
* @param[in] g The GDisplay structure
* @param[in] state TRUE = lcd in reset, FALSE = normal operation
*
* @notapi
*/
static inline void setpin_reset(GDisplay *g, bool_t state) {
(void) g;
(void) state;
}
/**
* @brief Take exclusive control of the bus
*
* @param[in] g The GDisplay structure
*
* @notapi
*/
static inline void acquire_bus(GDisplay *g) {
(void) g;
}
/**
* @brief Release exclusive control of the bus
*
* @param[in] g The GDisplay structure
*
* @notapi
*/
static inline void release_bus(GDisplay *g) {
(void) g;
}
/**
* @brief Send a command to the controller.
*
* @param[in] g The GDisplay structure
* @param[in] cmd The command to send *
*
* @notapi
*/
static inline void write_cmd(GDisplay *g, uint8_t cmd) {
(void) g;
(void) cmd;
}
/**
* @brief Send data to the lcd.
*
* @param[in] g The GDisplay structure
* @param[in] data The data to send
*
* @notapi
*/
static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
(void) g;
(void) data;
(void) length;
}
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -5,265 +5,258 @@
* http://ugfx.org/license.html * http://ugfx.org/license.html
*/ */
/**
* @file drivers/gdisp/ST7565/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for the ST7565 display.
*/
#include "gfx.h" #include "gfx.h"
#if GFX_USE_GDISP || defined(__DOXYGEN__) #if GFX_USE_GDISP
#define GDISP_DRIVER_VMT GDISPVMT_ST7565
#include "../drivers/gdisp/ST7565/gdisp_lld_config.h"
#include "gdisp/lld/gdisp_lld.h"
/* Include the emulation code for things we don't support */ #include "board_ST7565.h"
#include "gdisp/lld/emulation.c"
#include "st7565.h"
#include "gdisp_lld_board.h"
/*===========================================================================*/ /*===========================================================================*/
/* Driver local definitions. */ /* Driver local definitions. */
/*===========================================================================*/ /*===========================================================================*/
#ifndef GDISP_SCREEN_HEIGHT #ifndef GDISP_SCREEN_HEIGHT
#define GDISP_SCREEN_HEIGHT 64 #define GDISP_SCREEN_HEIGHT 64
#endif #endif
#ifndef GDISP_SCREEN_WIDTH #ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 128 #define GDISP_SCREEN_WIDTH 128
#endif
#ifndef GDISP_INITIAL_CONTRAST
#define GDISP_INITIAL_CONTRAST 51
#endif
#ifndef GDISP_INITIAL_BACKLIGHT
#define GDISP_INITIAL_BACKLIGHT 100
#endif #endif
#define GDISP_INITIAL_CONTRAST 0xFF #define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0)
#include "st7565.h"
/*===========================================================================*/ /*===========================================================================*/
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
// Some common routines and macros // Some common routines and macros
#define delay(us) gfxSleepMicroseconds(us) #define RAM(g) ((uint8_t *)g->priv)
#define delay_ms(ms) gfxSleepMilliseconds(ms) #define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); }
#define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); }
// The memory buffer for the display // Some common routines and macros
static uint8_t gdisp_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; #define delay(us) gfxSleepMicroseconds(us)
#define delay_ms(ms) gfxSleepMilliseconds(ms)
/** Set the display to normal or inverse. #define xyaddr(x, y) ((x) + ((y)>>3)*GDISP_SCREEN_WIDTH)
* @param[in] value 0 for normal mode, or 1 for inverse mode. #define xybit(y) (1<<((y)&7))
* @notapi
*/
static void invert_display(uint8_t i) {
write_cmd(i ? ST7565_INVERT_DISPLAY : ST7565_POSITIVE_DISPLAY);
}
/** Turn the whole display off.
* Sends the display to sleep, but leaves RAM intact.
* @notapi
*/
static void display_off(void) {
write_cmd(ST7565_DISPLAY_OFF);
}
/** Turn the whole display on.
* Wakes up this display following a sleep() call.
* @notapi
*/
static void display_on(void) {
write_cmd(ST7565_DISPLAY_ON);
}
/** Set the display contrast.
* @param[in] value The contrast, from 1 to 63.
* @notapi
*/
static void set_contrast(uint8_t value) {
write_cmd(ST7565_CONTRAST);
write_cmd(value & 0x3F);
}
/** Set the display start line. This is the line at which the display will start rendering.
* @param[in] value A value from 0 to 63 denoting the line to start at.
* @notapi
*/
static void set_display_start_line(unsigned char value) {
write_cmd(ST7565_START_LINE | value);
}
static void gdisp_lld_display(void) {
uint8_t p;
set_display_start_line(0);
for (p = 0; p < 8; p++) {
write_cmd(ST7565_PAGE | p);
write_cmd(ST7565_COLUMN_MSB | 0);
write_cmd(ST7565_COLUMN_LSB | 0);
write_cmd(ST7565_RMW);
write_data(&gdisp_buffer[p * GDISP_SCREEN_WIDTH], GDISP_SCREEN_WIDTH);
}
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported functions. */ /* Driver exported functions. */
/*===========================================================================*/ /*===========================================================================*/
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/** /**
* @brief Low level GDISP driver initialization. * As this controller can't update on a pixel boundary we need to maintain the
* * the entire display surface in memory so that we can do the necessary bit
* @notapi * operations. Fortunately it is a small display in monochrome.
* 64 * 128 / 8 = 1024 bytes.
*/ */
bool_t gdisp_lld_init(void) {
// Initialize your display
init_board();
// Hardware reset. LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
setpin_reset(TRUE); // The private area is the display surface.
delay_ms(10); g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8);
setpin_reset(FALSE);
delay_ms(1);
write_cmd(ST7565_LCD_BIAS_7); // Initialise the board interface
write_cmd(ST7565_ADC_NORMAL); init_board(g);
write_cmd(ST7565_COM_SCAN_INC);
set_display_start_line(0);
set_contrast(32); // Hardware reset
write_cmd(ST7565_RESISTOR_RATIO | 0x3); setpin_reset(g, TRUE);
gfxSleepMilliseconds(20);
setpin_reset(g, FALSE);
gfxSleepMilliseconds(20);
// turn on voltage converter (VC=1, VR=0, VF=0) acquire_bus(g);
write_cmd(ST7565_POWER_CONTROL | 0x04);
delay_ms(50);
// turn on voltage regulator (VC=1, VR=1, VF=0)
write_cmd(ST7565_POWER_CONTROL | 0x06);
delay_ms(50);
// turn on voltage follower (VC=1, VR=1, VF=1)
write_cmd(ST7565_POWER_CONTROL | 0x07);
delay_ms(50);
display_on(); write_cmd(g, ST7565_LCD_BIAS_7);
write_cmd(ST7565_ALLON_NORMAL); write_cmd(g, ST7565_ADC_NORMAL);
invert_display(0);// Disable Inversion of display. write_cmd(g, ST7565_COM_SCAN_INC);
write_cmd(g, ST7565_START_LINE | 0);
write_cmd(ST7565_RMW); write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101);
gdisp_lld_display(); write_cmd(g, ST7565_RESISTOR_RATIO | 0x3);
// Initialize the GDISP structure // turn on voltage converter (VC=1, VR=0, VF=0)
GDISP.Width = GDISP_SCREEN_WIDTH; write_cmd(g, ST7565_POWER_CONTROL | 0x04);
GDISP.Height = GDISP_SCREEN_HEIGHT; delay_ms(50);
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn; // turn on voltage regulator (VC=1, VR=1, VF=0)
GDISP.Contrast = 50; write_cmd(g, ST7565_POWER_CONTROL | 0x06);
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP delay_ms(50);
GDISP.clipx0 = 0;
GDISP.clipy0 = 0; // turn on voltage follower (VC=1, VR=1, VF=1)
GDISP.clipx1 = GDISP.Width; write_cmd(g, ST7565_POWER_CONTROL | 0x07);
GDISP.clipy1 = GDISP.Height; delay_ms(50);
#endif
return TRUE; write_cmd(g, ST7565_DISPLAY_ON);
write_cmd(g, ST7565_ALLON_NORMAL);
write_cmd(g, ST7565_POSITIVE_DISPLAY); // Disable Inversion of display.
write_cmd(g, ST7565_RMW);
// Finish Init
post_init_board(g);
// Release the bus
release_bus(g);
/* Initialise the GDISP structure */
g->g.Width = GDISP_SCREEN_WIDTH;
g->g.Height = GDISP_SCREEN_HEIGHT;
g->g.Orientation = GDISP_ROTATE_0;
g->g.Powermode = powerOn;
g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
g->g.Contrast = GDISP_INITIAL_CONTRAST;
return TRUE;
} }
/** #if GDISP_HARDWARE_FLUSH
* @brief Draws a pixel on the display. LLDSPEC void gdisp_lld_flush(GDisplay *g) {
* unsigned p;
* @param[in] x X location of the pixel
* @param[in] y Y location of the pixel // Don't flush if we don't need it.
* @param[in] color The color of the pixel if (!(g->flags & GDISP_FLG_NEEDFLUSH))
* return;
* @notapi
*/ acquire_bus(g);
void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { for (p = 0; p < 8; p++) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP write_cmd(g, ST7565_PAGE | p);
if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; write_cmd(g, ST7565_COLUMN_MSB | 0);
write_cmd(g, ST7565_COLUMN_LSB | 0);
write_cmd(g, ST7565_RMW);
write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH);
}
release_bus(g);
}
#endif #endif
if (color == 1) #if GDISP_HARDWARE_DRAWPIXEL
gdisp_buffer[x+ (y/8)*GDISP_SCREEN_WIDTH] |= (1<<y%8); LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
else coord_t x, y;
gdisp_buffer[x+ (y/8)*GDISP_SCREEN_WIDTH] &= ~(1<<y%8);
}
/* ---- Optional Routines ---- */ switch(g->g.Orientation) {
/* case GDISP_ROTATE_0:
All the below routines are optional. x = g->p.x;
Defining them will increase speed but everything y = g->p.y;
will work if they are not defined. break;
If you are not using a routine - turn it off using case GDISP_ROTATE_90:
the appropriate GDISP_HARDWARE_XXXX macro. x = g->p.y;
Don't bother coding for obvious similar routines if y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
there is no performance penalty as the emulation software break;
makes a good job of using similar routines. case GDISP_ROTATE_180:
eg. If gfillarea() is defined there is little x = GDISP_SCREEN_WIDTH-1 - g->p.x;
point in defining clear() unless the y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
performance bonus is significant. break;
For good performance it is suggested to implement case GDISP_ROTATE_270:
fillarea() and blitarea(). x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
*/ y = g->p.x;
break;
}
if (g->p.color != Black)
RAM(g)[xyaddr(x, y)] |= xybit(y);
else
RAM(g)[xyaddr(x, y)] &= ~xybit(y);
g->flags |= GDISP_FLG_NEEDFLUSH;
}
#endif
#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__) #if GDISP_HARDWARE_PIXELREAD
/** LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
* @brief Driver Control coord_t x, y;
* @details 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.
*
* @param[in] what What to do.
* @param[in] value The value to use (always cast to a void *).
*
* @notapi
*/
void gdisp_lld_control(unsigned what, void *value) {
switch(what) {
case GDISP_CONTROL_POWER:
if (GDISP.Powermode == (gdisp_powermode_t)value)
return;
switch((gdisp_powermode_t)value) { switch(g->g.Orientation) {
case powerOff: case GDISP_ROTATE_0:
display_off(); x = g->p.x;
break; y = g->p.y;
case powerSleep: break;
display_off(); case GDISP_ROTATE_90:
break; x = g->p.y;
case powerDeepSleep: y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
display_off(); break;
break; case GDISP_ROTATE_180:
case powerOn: x = GDISP_SCREEN_WIDTH-1 - g->p.x;
display_on(); y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
break; break;
default: case GDISP_ROTATE_270:
return; x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
} x = g->p.x;
GDISP.Powermode = (gdisp_powermode_t)value; break;
return; }
return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
}
#endif
case GDISP_CONTROL_BACKLIGHT: #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
set_backlight((uint8_t)(size_t)value); LLDSPEC void gdisp_lld_control(GDisplay *g) {
return; 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 powerSleep:
case powerDeepSleep:
acquire_bus(g);
write_cmd(g, ST7565_DISPLAY_OFF);
release_bus(g);
break;
case powerOn:
acquire_bus(g);
write_cmd(g, ST7565_DISPLAY_ON);
release_bus(g);
break;
default:
return;
}
g->g.Powermode = (powermode_t)g->p.ptr;
return;
case GDISP_CONTROL_CONTRAST: case GDISP_CONTROL_ORIENTATION:
if ((unsigned)value > 100) value = (void*)100; if (g->g.Orientation == (orientation_t)g->p.ptr)
if (GDISP.Contrast == (uint8_t)((float)((size_t)value) * 63.0/100.0)) return;
return; switch((orientation_t)g->p.ptr) {
set_contrast((uint8_t)((float)((size_t)value) * 63.0/100.0) ); /* Rotation is handled by the drawing routines */
GDISP.Contrast = (unsigned)value; case GDISP_ROTATE_0:
return; case GDISP_ROTATE_180:
g->g.Height = GDISP_SCREEN_HEIGHT;
g->g.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
case GDISP_ROTATE_270:
g->g.Height = GDISP_SCREEN_WIDTH;
g->g.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
g->g.Orientation = (orientation_t)g->p.ptr;
return;
case GDISP_CONTROL_LLD_FLUSH: case GDISP_CONTROL_CONTRAST:
gdisp_lld_display(); if ((unsigned)g->p.ptr > 100)
return; g->p.ptr = (void *)100;
} acquire_bus(g);
} write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F);
release_bus(g);
g->g.Contrast = (unsigned)g->p.ptr;
return;
}
}
#endif // GDISP_NEED_CONTROL #endif // GDISP_NEED_CONTROL
#endif // GFX_USE_GDISP #endif // GFX_USE_GDISP
/** @} */

View File

@ -1,6 +1,2 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/ST7565/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/ST7565 GFXINC += $(GFXLIB)/drivers/gdisp/ST7565
GFXSRC += $(GFXLIB)/drivers/gdisp/ST7565/gdisp_lld.c

View File

@ -1,82 +0,0 @@
/*
* 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_BOARD_H
#define _GDISP_LLD_BOARD_H
/**
* @brief Initialize the board for the display.
* @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
* @notapi
*/
static inline void init_board(void) {
/* Configure SPI bus here. Up to 10Mhz, SPI Mode = 3 (CPOL = 1, CPHA = 0) */
/* Configure A0, !CS, !RST pin for output */
}
/**
* @brief Set or clear the lcd reset pin.
* @param[in] state TRUE = lcd in reset, FALSE = normal operation
* @notapi
*/
static inline void setpin_reset(bool_t state) {
/* Set !CS to low */
if (state) {
/* Set !RST to low */
} else {
/* Set !RST to high */
}
}
/**
* @brief Set the lcd back-light level.
* @param[in] percent 0 to 100%
* @notapi
*/
static inline void set_backlight(uint8_t percent) {
}
/**
* @brief Take exclusive control of the bus
* @notapi
*/
static inline void acquire_bus(void) {
}
/**
* @brief Release exclusive control of the bus
* @notapi
*/
static inline void release_bus(void) {
}
/**
* @brief Send command to the display.
* @param[in] cmd The command to send
* @notapi
*/
static inline void write_cmd(uint8_t cmd) {
/* Set A0 to low */
/* Transmit cmd over SPI */
}
/**
* @brief Send data to the display.
* @param[in] data The data to send
* @notapi
*/
static inline void write_data(uint8_t* data, uint16_t length) {
/* Set A0 to high */
/* Transmit data for length over SPI. DMA is recommended. */
}
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -14,13 +14,12 @@
/* Driver hardware support. */ /* Driver hardware support. */
/*===========================================================================*/ /*===========================================================================*/
#define GDISP_DRIVER_NAME "ST7565" #define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing
#define GDISP_HARDWARE_DRAWPIXEL TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_HARDWARE_CONTROL TRUE #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_MONO
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_MONO
#define GDISP_CONTROL_LLD_FLUSH (GDISP_CONTROL_LLD + 1)
#endif /* GFX_USE_GDISP */ #endif /* GFX_USE_GDISP */