diff --git a/drivers/gdisp/TLS8204/TLS8204.h b/drivers/gdisp/TLS8204/TLS8204.h new file mode 100644 index 00000000..46511a79 --- /dev/null +++ b/drivers/gdisp/TLS8204/TLS8204.h @@ -0,0 +1,87 @@ +/* + * 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 _TLS8204_H +#define _TLS8204_H + +// H1H0=xx ========================================= + +#define TLS8204_NOP 0x00 // H1H0=xx: NOP - 0 0 0 0 0 0 0 0 +#define TLS8204_SET_FUNC 0x20 // H1H0=xx: Function set - 0 0 1 MX MY PD H1 H0 + #define TLS8204_H0_BIT 0x01 + #define TLS8204_H1_BIT 0x02 + #define TLS8204_PD_BIT 0x04 + #define TLS8204_MX_BIT 0x08 + #define TLS8204_MY_BIT 0x10 + +// H1H0=00 ========================================= + +#define TLS8204_SET_VLCD7 0x04 // H1H0=00: Set Contrast bit7 - 0 0 0 0 0 1 0 V7 + +#define TLS8204_SET_DISPLAY_OFF 0x08 // H1H0=00: Display Control - 0 0 0 0 1 D 0 E (D = 0, E = 0) +#define TLS8204_SET_DISPLAY_FILL 0x09 // H1H0=00: Display Control - 0 0 0 0 1 D 0 E (D = 0, E = 1) +#define TLS8204_SET_DISPLAY_NORMAL 0x0C // H1H0=00: Display Control - 0 0 0 0 1 D 0 E (D = 1, E = 0) +#define TLS8204_SET_DISPLAY_INVERT 0x0D // H1H0=00: Display Control - 0 0 0 0 1 D 0 E (D = 1, E = 1) + +#define TLS8204_SET_Y 0x40 // H1H0=00: Set Y/8 (page) - 0 1 0 0 Y3 Y2 Y1 Y0 +#define TLS8204_SET_X 0x80 // H1H0=00: Set X (column) - 1 X6 X5 X4 X3 X2 X1 X0 + +// H1H0=01 ========================================= + +#define TLS8204_SET_STARTLINE_S6 0x04 // H1H0=01: Set Startline S6 - 0 0 0 0 0 1 0 S6 +#define TLS8204_SET_STARTLINE_S0_5 0x40 // H1H0=01: Set Startline S0-5 - 0 1 S5 S4 S3 S2 S1 S0 + +#define TLS8204_SET_Y_LSB_FIRST 0x08 // H1H0=01: Set Y to LSB first - 0 0 0 0 1 D0 x x (D0 = 0) +#define TLS8204_SET_Y_MSB_FIRST 0x0C // H1H0=01: Set Y to LSB first - 0 0 0 0 1 D0 x x (D0 = 1) + +#define TLS8204_SET_BIAS_7 0x10 // H1H0=01: Set Bias 1/100 - 0 0 0 1 0 B2 B1 B0 +#define TLS8204_SET_BIAS_6 0x11 // H1H0=01: Set Bias 1/81 - 0 0 0 1 0 B2 B1 B0 +#define TLS8204_SET_BIAS_5 0x12 // H1H0=01: Set Bias 1/65,68 - 0 0 0 1 0 B2 B1 B0 +#define TLS8204_SET_BIAS_4 0x13 // H1H0=01: Set Bias 1/49 - 0 0 0 1 0 B2 B1 B0 +#define TLS8204_SET_BIAS_3 0x14 // H1H0=01: Set Bias 1/40,36 - 0 0 0 1 0 B2 B1 B0 +#define TLS8204_SET_BIAS_2 0x15 // H1H0=01: Set Bias 1/24 - 0 0 0 1 0 B2 B1 B0 +#define TLS8204_SET_BIAS_1 0x16 // H1H0=01: Set Bias 1/18,16 - 0 0 0 1 0 B2 B1 B0 +#define TLS8204_SET_BIAS_0 0x17 // H1H0=01: Set Bias 1/10,9,8 - 0 0 0 1 0 B2 B1 B0 + +#define TLS8204_SET_VLCD0_6 0x80 // H1H0=01: Set Contrast Bit0-6 - 1 V6 V5 V4 V3 V2 V1 V0 (Real range 36 - 219) + +// H1H0=10 ========================================= + +#define TLS8204_SET_PARTIAL_OFF 0x04 // H1H0=10: Partial Mode Off - 0 0 0 0 0 1 0 PS (PS = 0) +#define TLS8204_SET_PARTIAL_ON 0x05 // H1H0=10: Partial Mode On - 0 0 0 0 0 1 0 PS (PS = 1) + +#define TLS8204_SET_PARTIAL16 0x08 // H1H0=10: 16 line Partial - 0 0 0 0 1 0 0 WS (WS = 0) +#define TLS8204_SET_PARTIAL32 0x09 // H1H0=10: 32 line Partial - 0 0 0 0 1 0 0 WS (WS = 1) + +#define TLS8204_SET_PARTIAL_Y 0x10 // H1H0=10: The Partial Y/8 (pg)- 0 0 0 1 0 P2 P1 P0 + +// H1H0=11 ========================================= + +#define TLS8204_RESET 0x03 // H1H0=11: Reset - 0 0 0 0 0 0 1 1 + +#define TLS8204_SET_FREQ55 0x08 // H1H0=11: Frame Frequency - 0 0 0 0 1 F2 F1 F0 (F = 0) +#define TLS8204_SET_FREQ65 0x09 // H1H0=11: Frame Frequency - 0 0 0 0 1 F2 F1 F0 (F = 1) +#define TLS8204_SET_FREQ68 0x0A // H1H0=11: Frame Frequency - 0 0 0 0 1 F2 F1 F0 (F = 2) +#define TLS8204_SET_FREQ70 0x0B // H1H0=11: Frame Frequency - 0 0 0 0 1 F2 F1 F0 (F = 3) +#define TLS8204_SET_FREQ73 0x0C // H1H0=11: Frame Frequency - 0 0 0 0 1 F2 F1 F0 (F = 4) +#define TLS8204_SET_FREQ76 0x0D // H1H0=11: Frame Frequency - 0 0 0 0 1 F2 F1 F0 (F = 5) +#define TLS8204_SET_FREQ80 0x0E // H1H0=11: Frame Frequency - 0 0 0 0 1 F2 F1 F0 (F = 6) +#define TLS8204_SET_FREQ137 0x0F // H1H0=11: Frame Frequency - 0 0 0 0 1 F2 F1 F0 (F = 7) + +#define TLS8204_SET_INVERSION 0x40 // H1H0=11: Set line inversion - 0 1 0 L4 L3 L2 L1 L0 (Lines = 0 or L+2) + +#define TLS8204_SET_BOOST 0x50 // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 + #define TLS8204_BOOST_EFFICIENCY1 0x5C // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 (E1E0 = 3) + #define TLS8204_BOOST_EFFICIENCY2 0x58 // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 (E1E0 = 2) + #define TLS8204_BOOST_EFFICIENCY3 0x54 // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 (E1E0 = 1) + #define TLS8204_BOOST_EFFICIENCY4 0x50 // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 (E1E0 = 0) + #define TLS8204_BOOST_5X 0x53 // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 (B1B0 = 3) + #define TLS8204_BOOST_4X 0x52 // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 (B1B0 = 2) + #define TLS8204_BOOST_3X 0x51 // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 (B1B0 = 1) + #define TLS8204_BOOST_2X 0x50 // H1H0=11: Set Boost - 1 0 0 1 E1 E0 B1 B0 (B1B0 = 0) + +#endif /* _TLS8204_H */ diff --git a/drivers/gdisp/TLS8204/board_TLS8204_template.h b/drivers/gdisp/TLS8204/board_TLS8204_template.h new file mode 100644 index 00000000..08ec130d --- /dev/null +++ b/drivers/gdisp/TLS8204/board_TLS8204_template.h @@ -0,0 +1,43 @@ +/* + * 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 + +static inline void init_board(GDisplay *g) { + (void) g; +} + +static inline void post_init_board(GDisplay *g) { + (void) g; +} + +static inline void setpin_reset(GDisplay *g, bool_t state) { + (void) g; + (void) state; +} + +static inline void acquire_bus(GDisplay *g) { + (void) g; +} + +static inline void release_bus(GDisplay *g) { + (void) g; +} + +static inline void write_cmd(GDisplay *g, uint8_t cmd) { + (void) g; + (void) cmd; +} + +static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) { + (void) g; + (void) data; + (void) length; +} + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/drivers/gdisp/TLS8204/driver.mk b/drivers/gdisp/TLS8204/driver.mk new file mode 100644 index 00000000..46ee3da3 --- /dev/null +++ b/drivers/gdisp/TLS8204/driver.mk @@ -0,0 +1,2 @@ +GFXINC += $(GFXLIB)/drivers/gdisp/TLS8204 +GFXSRC += $(GFXLIB)/drivers/gdisp/TLS8204/gdisp_lld_TLS8204.c diff --git a/drivers/gdisp/TLS8204/gdisp_lld_TLS8204.c b/drivers/gdisp/TLS8204/gdisp_lld_TLS8204.c new file mode 100644 index 00000000..7a9e7415 --- /dev/null +++ b/drivers/gdisp/TLS8204/gdisp_lld_TLS8204.c @@ -0,0 +1,245 @@ +/* + * 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 + +#define GDISP_DRIVER_VMT GDISPVMT_TLS8204 +#include "drivers/gdisp/TLS8204/gdisp_lld_config.h" +#include "src/gdisp/gdisp_driver.h" +#include "board_TLS8204.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define GDISP_TLS8204_HEIGHT 48 +#define GDISP_TLS8204_WIDTH 84 + +#define GDISP_INITIAL_CONTRAST 51 +#define GDISP_INITIAL_BACKLIGHT 100 + +#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) + +#include "drivers/gdisp/TLS8204/TLS8204.h" + +/*===========================================================================*/ +/* Driver local routines. */ +/*===========================================================================*/ + +// Some common routines and macros +#define RAM(g) ((uint8_t *)g->priv) + +#define xyaddr(x, y) ((x) + ((y) >> 3) * GDISP_TLS8204_WIDTH) +#define xybit(y) (1 << ((y) & 7)) + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/* + * 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 + * operations. Fortunately it is a small display in monochrome. + * Display 48 * 84 / 8 = 504 bytes + */ + +#define GDISP_SCREEN_BYTES ((GDISP_TLS8204_WIDTH * GDISP_TLS8204_HEIGHT) / 8) + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { + // The private area is the display surface. + if (!(g->priv = gfxAlloc(GDISP_SCREEN_BYTES))) + gfxHalt("GDISP TLS8204: Failed to allocate private memory"); + + // Initialise the board interface + init_board(g); + + // Hardware reset + setpin_reset(g, TRUE); + gfxSleepMilliseconds(100); + setpin_reset(g, FALSE); + gfxSleepMilliseconds(100); + + acquire_bus(g); + + // Soft reset - display on + write_cmd(g, TLS8204_SET_FUNC | TLS8204_H0_BIT | TLS8204_H1_BIT); + write_cmd(g, TLS8204_RESET); + gfxSleepMilliseconds(100); + + // H0H1 = 01 + write_cmd(g, TLS8204_SET_FUNC | TLS8204_H0_BIT); + write_cmd(g, TLS8204_SET_BIAS_4); + write_cmd(g, TLS8204_SET_Y_LSB_FIRST); + write_cmd(g, TLS8204_SET_VLCD0_6 + ((GDISP_INITIAL_CONTRAST * 2 + 22) & 0x7F)); + + // H0H1 = 00 + write_cmd(g, TLS8204_SET_FUNC); + write_cmd(g, TLS8204_SET_VLCD7 + ((GDISP_INITIAL_CONTRAST * 2 + 22) >> 7)); + write_cmd(g, TLS8204_SET_DISPLAY_NORMAL); + write_cmd(g, TLS8204_SET_X + 0); + write_cmd(g, TLS8204_SET_Y + 0/8); + + // Finish Init + post_init_board(g); + + // Release the bus + release_bus(g); + + /* Turn on the back-light */ + set_backlight(g, GDISP_INITIAL_BACKLIGHT); + + /* Initialise the GDISP structure */ + g->g.Width = GDISP_TLS8204_WIDTH; + g->g.Height = GDISP_TLS8204_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 + LLDSPEC void gdisp_lld_flush(GDisplay *g) { + + // Don't flush if we don't need it. + if (!(g->flags & GDISP_FLG_NEEDFLUSH)) + return; + + acquire_bus(g); + + write_cmd(g, TLS8204_SET_X + 0); // X = 0 + write_cmd(g, TLS8204_SET_Y + 0/8); // Y = 0 + + write_data(g, RAM(g), GDISP_SCREEN_BYTES); + + release_bus(g); + } +#endif + +#if GDISP_HARDWARE_DRAWPIXEL + LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + coord_t x, y; + + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + x = g->p.x; + y = g->p.y; + break; + case GDISP_ROTATE_90: + x = g->p.y; + y = g->g.Width - g->p.x - 1; + break; + case GDISP_ROTATE_180: + x = g->g.Width - g->p.x - 1; + y = g->g.Height - g->p.y - 1; + break; + case GDISP_ROTATE_270: + x = g->g.Height - g->p.y - 1; + y = g->p.x; + break; + } + #else + x = g->p.x; + y = g->p.y; + #endif + + if (gdispColor2Native(g->p.color) != gdispColor2Native(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 + 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 powerSleep: + case powerDeepSleep: + acquire_bus(g); + write_cmd(g, TLS8204_SET_FUNC | TLS8204_PD_BIT); + release_bus(g); + break; + case powerOn: + acquire_bus(g); + write_cmd(g, TLS8204_SET_FUNC); + release_bus(g); + 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; + set_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; + { + uint8_t cval; + + cval = (unsigned)g->p.ptr * 2 + 22; + acquire_bus(g); + write_cmd(g, TLS8204_SET_FUNC | TLS8204_H0_BIT); // H1H0 = 01 + write_cmd(g, TLS8204_SET_VLCD0_6 + (cval & 0x7F)); + write_cmd(g, TLS8204_SET_FUNC); // H1H0 = 00 + write_cmd(g, TLS8204_SET_VLCD7 + (cval >> 7)); + release_bus(g); + } + g->g.Contrast = (unsigned)g->p.ptr; + return; + } + } +#endif + +#endif // GFX_USE_GDISP diff --git a/drivers/gdisp/TLS8204/gdisp_lld_config.h b/drivers/gdisp/TLS8204/gdisp_lld_config.h new file mode 100644 index 00000000..6ad8a571 --- /dev/null +++ b/drivers/gdisp/TLS8204/gdisp_lld_config.h @@ -0,0 +1,28 @@ +/* + * 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_FLUSH TRUE // This controller requires flushing +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_CONTROL TRUE + +// Set this to your frame buffer pixel format. +#ifndef GDISP_LLD_PIXELFORMAT + #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO +#endif + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */