diff options
34 files changed, 1405 insertions, 1192 deletions
diff --git a/changelog.txt b/changelog.txt index eec3cc1d..4bc85283 100644 --- a/changelog.txt +++ b/changelog.txt @@ -39,6 +39,11 @@ FEATURE: Added KS0108 driver FEATURE: Added RA6963 driver
FIX: Fixed clipping issue in gdispGDrawString()
CHANGE: Upgrade GFILE FATFS support from V0.10b to V0.13
+FEATURE: Added UC1610 driver
+FIX: Fixed to allow gwinSetText with static text on a TextEdit control
+FIX: Fixed to ChibiOS realloc on a TextEdit control
+FEATURE: Added support for CMSIS V2.0 operating systems (eg RTX5)
+REMOVED: Removed long deprecated functions gfxSemCounter() and gfxSemCounterI()
*** Release 2.7 ***
@@ -92,7 +97,7 @@ FEATURE: Added support for IAR and EDG compilers FIX: Fixed crash when loading GIF image without enough memory available
FEATURE: Added games/minesweeper demo
FEATURE: Added games/justget10 demo
-
+
*** Release 2.5 ***
FEATURE: Added support for numerous compilers
diff --git a/drivers/gdisp/UC1610/UC1610.h b/drivers/gdisp/UC1610/UC1610.h new file mode 100644 index 00000000..f6d3d23d --- /dev/null +++ b/drivers/gdisp/UC1610/UC1610.h @@ -0,0 +1,65 @@ +/* + * 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://chibios-gfx.com/license.html + */ + +#ifndef _UC1610_H +#define _UC1610_H + + // screen dimensions + #define UC1610_SCREEN_WIDTH 160 + #define UC1610_SCREEN_HEIGHT 104 + #define UC1610_PAGE_HEIGHT 4 + + // i2c header addresses + #define UC1610_ADDRESS_WC 0x78 // write commands + #define UC1610_ADDRESS_RS 0x79 // read satus + #define UC1610_ADDRESS_WD 0x7A // write data + #define UC1610_ADDRESS_RD 0x7B // read data + + // hardware control commands + #define UC1610_SYSTEM_RESET 0xE2 + #define UC1610_NOP 0xE3 // no operation + #define UC1610_SET_TEMP_COMP 0x24 // set temperature compensation, default -0.05%/°C + #define UC1610_SET_PANEL_LOADING 0x29 // set panel loading, default 16~21 nF + #define UC1610_SET_PUMP_CONTROL 0x2F // default internal Vlcd (8x pump) + #define UC1610_SET_LCD_BIAS_RATIO 0xEB // default 11 + #define UC1610_SET_VBIAS_POT 0x81 // 1 byte (0~255) to follow setting the contrast, default 0x81 + #define UC1610_SET_LINE_RATE 0xA0 // default 12,1 Klps + #define UC1610_SET_DISPLAY_ENABLE 0xAE // + 1 mask / 0 : exit sleep mode / entering sleep mode + #define UC1610_SET_LCD_GRAY_SHADE 0xD0 // default 24% between the two gray shade levels + #define UC1610_SET_COM_END 0xF1 // set the number of used com electrodes (lines number -1) + + // ram address control + #define UC1610_SET_AC 0x88 // set ram addres control + #define UC1610_AC_WA_MASK 1 // automatic column/page increment wrap arroud (1 : cycle increment) + #define UC1610_AC_AIO_MASK (1 << 1) // auto increment order (0/1 : column/page increment first) + #define UC1610_AC_PID_MASK (1 << 2) // page addres auto increment order (0/1 : +1/-1) + + // set cursor ram address + #define UC1610_SET_CA_LSB 0x00 // + 4 LSB bits + #define UC1610_SET_CA_MSB 0x10 // + 4 MSB bits // MSB + LSB values range : 0~159 + #define UC1610_SET_PA 0x60 // + 5 bits // values range : 0~26 + + // display control commands + #define UC1610_SET_FIXED_LINES 0x90 // + 4 bits = 2xFL + #define UC1610_SET_SCROLL_LINES_LSB 0x40 // + 4 LSB bits scroll up display by N (7 bits) lines + #define UC1610_SET_SCROLL_LINES_MSB 0x50 // + 3 MSB bits + #define UC1610_SET_ALL_PIXEL_ON 0xA4 // + 1 mask / 0 : set all pixel on, reverse + #define UC1610_SET_INVERSE_DISPLAY 0xA6 // + 1 mask / 0 : inverse all data stored in ram, reverse + #define UC1610_SET_MAPPING_CONTROL 0xC0 // control mirorring + #define UC1610_SET_MAPPING_CONTROL_LC_MASK 1 // + #define UC1610_SET_MAPPING_CONTROL_MX_MASK (1 << 1) // + #define UC1610_SET_MAPPING_CONTROL_MY_MASK (1 << 2) // + + // window program mode + #define UC1610_SET_WINDOW_PROGRAM_ENABLE 0xF8 // + 1 mask / 0 : enable / disable window programming mode, + // reset before changing boundaries + #define UC1610_SET_WP_STARTING_CA 0xF4 // 1 byte to follow for column number + #define UC1610_SET_WP_ENDING_CA 0xF6 // 1 byte to follow for column number + #define UC1610_SET_WP_STARTING_PA 0xF5 // 1 byte to follow for page number + #define UC1610_SET_WP_ENDING_PA 0xF7 // 1 byte to follow for page number + +#endif /* _SSD1306_H */ diff --git a/drivers/gdisp/UC1610/board_UC1610_template.h b/drivers/gdisp/UC1610/board_UC1610_template.h new file mode 100644 index 00000000..206e7c88 --- /dev/null +++ b/drivers/gdisp/UC1610/board_UC1610_template.h @@ -0,0 +1,45 @@ +/* + * 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 GFXINLINE void init_board(GDisplay *g) { + (void) g; +} + +static GFXINLINE void post_init_board(GDisplay *g) { + (void) g; +} + +static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) { + (void) g; + (void) state; +} + +static GFXINLINE void acquire_bus(GDisplay *g) { + (void) g; +} + +static GFXINLINE void release_bus(GDisplay *g) { + (void) g; +} + +static GFXINLINE void write_cmd(GDisplay *g, uint8_t * cmd, uint8_t length) { + (void) g; + (void) cmd; + (void) length; +} + +static GFXINLINE 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/UC1610/driver.mk b/drivers/gdisp/UC1610/driver.mk new file mode 100644 index 00000000..b12bc6a5 --- /dev/null +++ b/drivers/gdisp/UC1610/driver.mk @@ -0,0 +1,2 @@ +GFXINC += $(GFXLIB)/drivers/gdisp/UC1610 +GFXSRC += $(GFXLIB)/drivers/gdisp/UC1610/gdisp_lld_UC1610.c diff --git a/drivers/gdisp/UC1610/gdisp_lld_UC1610.c b/drivers/gdisp/UC1610/gdisp_lld_UC1610.c new file mode 100644 index 00000000..b602c991 --- /dev/null +++ b/drivers/gdisp/UC1610/gdisp_lld_UC1610.c @@ -0,0 +1,322 @@ +/* + * 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_UC1610 +#include "gdisp_lld_config.h" +#include "../../../src/gdisp/gdisp_driver.h" + +#include "board_UC1610.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#include "UC1610.h" + +#ifndef GDISP_SCREEN_HEIGHT + #define GDISP_SCREEN_HEIGHT UC1610_SCREEN_HEIGHT +#endif + +#ifndef GDISP_SCREEN_WIDTH + #define GDISP_SCREEN_WIDTH UC1610_SCREEN_WIDTH +#endif + +#ifndef GDISP_INITIAL_CONTRAST + #define GDISP_INITIAL_CONTRAST 40 +#endif + +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 100 +#endif + +// Some common routines and macros +#define PRIV(g) ((UC1610_Window *)g->priv) +#define RAM(g) ((uint8_t *)(PRIV(g) + 1)) +#define xyaddr(x, y) ((x) + GDISP_SCREEN_WIDTH * ((y) >> 2)) +#define xybit(y, c) ((c) << (((y) & 3) << 1)) +#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) + +typedef struct UC1610_Window { + coord_t x1; + coord_t y1; + coord_t x2; + coord_t y2; +} UC1610_Window; + +/*===========================================================================*/ +/* Driver local varriables. */ +/*===========================================================================*/ + +static uint8_t cmdBuffer[11]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static void GFXINLINE power_on_sequence(GDisplay* g) { + cmdBuffer[0] = UC1610_SYSTEM_RESET; // software reset + write_cmd(g, cmdBuffer, 1); + gfxSleepMilliseconds(2); + cmdBuffer[0] = UC1610_SET_COM_END; // set com end value + cmdBuffer[1] = GDISP_SCREEN_HEIGHT - 1; + cmdBuffer[2] = UC1610_SET_PANEL_LOADING; + cmdBuffer[3] = UC1610_SET_LCD_BIAS_RATIO; + cmdBuffer[4] = UC1610_SET_VBIAS_POT; // set contrast + cmdBuffer[5] = (uint8_t) (GDISP_INITIAL_CONTRAST * 254 / 100); + cmdBuffer[6] = UC1610_SET_MAPPING_CONTROL; // bottom view + cmdBuffer[7] = UC1610_SET_SCROLL_LINES_LSB | 0; + cmdBuffer[8] = UC1610_SET_SCROLL_LINES_MSB | 0; // set scroll line on line 0 + cmdBuffer[9] = UC1610_SET_AC | UC1610_AC_WA_MASK; // set auto increment wrap arround + cmdBuffer[10] = UC1610_SET_DISPLAY_ENABLE | 1; // turn display on + write_cmd(g, cmdBuffer, 11); +} + +static void GFXINLINE flush_screen(GDisplay* g) { + PRIV(g)->x1 = 0; + PRIV(g)->y1 = 0; + PRIV(g)->x2 = GDISP_SCREEN_WIDTH-1; + PRIV(g)->y2 = GDISP_SCREEN_HEIGHT-1; + g->flags |= GDISP_FLG_NEEDFLUSH; + gdisp_lld_flush(g); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { + // The private area is the display surface + flush window structure. + g->priv = gfxAlloc(sizeof(UC1610_Window) + GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT / UC1610_PAGE_HEIGHT); + + // Initialise the board interface + init_board(g); + + // Hardware reset + // not needed : reset pin set to ON by init_board(g), software reset by power_on_sequence(g) + gfxSleepMilliseconds(12); + + // Acquire the bus + acquire_bus(g); + + // Init commands sequence + power_on_sequence(g); + + // 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_DRAWPIXEL + LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + coord_t x, y; + uint8_t *c; + + // handle orientation + switch (g->g.Orientation) { + default : + x = g->p.x; + y = g->p.y; + break; + case GDISP_ROTATE_90 : + y = g->p.x; + x = g->p.y; + break; + case GDISP_ROTATE_270 : + y = g->p.x; + x = g->p.y; + break; + } + + + // update pixel color + c = RAM(g) + xyaddr(x, y); + *c &= ~xybit(y, LLDCOLOR_MASK()); + *c |= xybit(y, gdispColor2Native(g->p.color)); + + // update flush window boundaries + if (x < PRIV(g)->x1) { PRIV(g)->x1 = x; } + if (x > PRIV(g)->x2) { PRIV(g)->x2 = x; } + if (y < PRIV(g)->y1) { PRIV(g)->y1 = y; } + if (y > PRIV(g)->y2) { PRIV(g)->y2 = y; } + g->flags |= GDISP_FLG_NEEDFLUSH; + } +#endif + +#if GDISP_HARDWARE_FLUSH + LLDSPEC void gdisp_lld_flush(GDisplay* g) + { + coord_t x1, y1, x2, y2, cx; + uint8_t *c; + + // Don't flush unless we really need to + if (!(g->flags & GDISP_FLG_NEEDFLUSH)) + return; + + x1 = PRIV(g)->x1; + y1 = PRIV(g)->y1; + x2 = PRIV(g)->x2; + y2 = PRIV(g)->y2; + cx = x2 - x1 + 1; + + // Clear the 'need-flushing' flag and reset the window + g->flags &= ~GDISP_FLG_NEEDFLUSH; + PRIV(g)->x1 = GDISP_SCREEN_WIDTH; + PRIV(g)->y1 = GDISP_SCREEN_HEIGHT; + PRIV(g)->x2 = -1; + PRIV(g)->y2 = -1; + + // set window to fill + cmdBuffer[0] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 0; // before changing boundaries + cmdBuffer[1] = UC1610_SET_WP_STARTING_CA; + cmdBuffer[2] = x1; + cmdBuffer[3] = UC1610_SET_WP_ENDING_CA; + cmdBuffer[4] = x2; + cmdBuffer[5] = UC1610_SET_WP_STARTING_PA; + cmdBuffer[6] = y1 >> 2; + cmdBuffer[7] = UC1610_SET_WP_ENDING_PA; + cmdBuffer[8] = y2 >> 2; + cmdBuffer[9] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 1; // entering window programming + + acquire_bus(g); + write_cmd (g, cmdBuffer, 10); + + // write each page segment from RAM(g) to display RAM + for (c = RAM(g) + xyaddr(x1, y1) ; y1 <= y2 ; c += GDISP_SCREEN_WIDTH, y1 += UC1610_PAGE_HEIGHT) { + write_data(g, c, cx); + } + release_bus(g); + } +#endif + +#if GDISP_NEED_CONTROL && GDISP_HARDWARE_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: + cmdBuffer[0] = UC1610_SYSTEM_RESET; + acquire_bus(g); + write_cmd(g, cmdBuffer, 1); + release_bus(g); + gfxSleepMilliseconds(2); + break; + case powerSleep: + cmdBuffer[0] = UC1610_SET_DISPLAY_ENABLE | 0; + acquire_bus(g); + write_cmd(g, cmdBuffer, 1); + release_bus(g); + gfxSleepMilliseconds(2); + break; + case powerOn: + if (g->g.Powermode == powerSleep) { + cmdBuffer[0] = UC1610_SET_DISPLAY_ENABLE | 1; + acquire_bus(g); + write_cmd(g, cmdBuffer, 1); + release_bus(g); + flush_screen(g); + } else { + gfxSleepMilliseconds(12); + acquire_bus(g); + power_on_sequence(g); + 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: + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + cmdBuffer[0] = UC1610_SET_MAPPING_CONTROL; + acquire_bus(g); + write_cmd(g, cmdBuffer, 1); + release_bus(g); + flush_screen(g); + break; + case GDISP_ROTATE_180: // we can rotate 180° without modify screen buffer RAM(g) + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + cmdBuffer[0] = UC1610_SET_MAPPING_CONTROL | UC1610_SET_MAPPING_CONTROL_MY_MASK | UC1610_SET_MAPPING_CONTROL_MX_MASK; + acquire_bus(g); + write_cmd(g, cmdBuffer, 1); + release_bus(g); + flush_screen(g); + break; + case GDISP_ROTATE_90: // needs clearing screen and updating RAM(g) + g->g.Width = GDISP_SCREEN_HEIGHT; + g->g.Height = GDISP_SCREEN_WIDTH; + cmdBuffer[0] = UC1610_SET_MAPPING_CONTROL | UC1610_SET_MAPPING_CONTROL_MX_MASK; + acquire_bus(g); + write_cmd(g, cmdBuffer, 1); + release_bus(g); + break; + case GDISP_ROTATE_270: // needs clearing screen and updating RAM(g) + g->g.Width = GDISP_SCREEN_HEIGHT; + g->g.Height = GDISP_SCREEN_WIDTH; + cmdBuffer[0] = UC1610_SET_MAPPING_CONTROL | UC1610_SET_MAPPING_CONTROL_MY_MASK; + acquire_bus(g); + write_cmd(g, cmdBuffer, 1); + release_bus(g); + break; + default: + return; + } + g->g.Orientation = (orientation_t)g->p.ptr; + return; + + case GDISP_CONTROL_BACKLIGHT: + // TODO: backlight support at board level + /*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; } + acquire_bus(g); + cmdBuffer[0] = UC1610_SET_VBIAS_POT; + cmdBuffer[1] = (uint8_t)((unsigned)g->p.ptr * 254 / 100); + write_cmd(g, cmdBuffer, 2); + release_bus(g); + g->g.Contrast = (unsigned)g->p.ptr; + flush_screen(g); + return; + + case GDISP_CONTROL_INVERSE: + cmdBuffer[0] = g->p.ptr ? (UC1610_SET_INVERSE_DISPLAY | 1) : (UC1610_SET_INVERSE_DISPLAY | 0); + acquire_bus(g); + write_cmd(g, cmdBuffer, 1); + release_bus(g); + //flush_screen(g); + return; + } + } +#endif + +#endif // GFX_USE_GDISP diff --git a/drivers/gdisp/UC1610/gdisp_lld_config.h b/drivers/gdisp/UC1610/gdisp_lld_config.h new file mode 100644 index 00000000..36e37ad5 --- /dev/null +++ b/drivers/gdisp/UC1610/gdisp_lld_config.h @@ -0,0 +1,29 @@ +/* + * 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 +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_CONTROL TRUE + +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY4 + +// This controller supports a special gdispControl() to inverse the display. +// Pass a parameter of 1 for inverse and 0 for normal. +#define GDISP_CONTROL_INVERSE (GDISP_CONTROL_LLD+0) + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/drivers/gdisp/UC8173/UC8173.h b/drivers/gdisp/UC8173/UC8173.h index a38fd573..e0e97eeb 100644 --- a/drivers/gdisp/UC8173/UC8173.h +++ b/drivers/gdisp/UC8173/UC8173.h @@ -96,814 +96,5 @@ #define Initial_Counter 64 #define Temperature_LUT_Counter 672 -static uint8_t const _lut_None[] = { - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00 -}; - - -static uint8_t const _lut_KWvcom_DC_GU[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x0C, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -static uint8_t const _lut_KWvcom_DC_A2_240ms[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x0C, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -static uint8_t const _lut_KWvcom_DC_A2_120ms[] = { - 0x00, - 0x00, - 0x00, - 0x0C, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - - -static uint8_t const _lut_kw_GU[] = { - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - - -static uint8_t const _lut_kw_A2_240ms[] = { - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -static uint8_t const _lut_kw_A2_120ms[] = { - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - - -static uint8_t const _lut_KWvcom[] = { - 0x55, - 0x6A, - 0xA5, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x56, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0x0C, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -static uint8_t const _lut_kw[] = { - 0x41, 0x00, 0x00, 0x81, - 0x41, 0x00, 0x00, 0x81, - 0x41, 0x00, 0x00, 0x81, - 0x41, 0x00, 0x00, 0x81, - 0x41, 0x00, 0x00, 0x81, - 0x81, 0x00, 0x00, 0x82, - 0x81, 0x00, 0x00, 0x82, - 0x81, 0x00, 0x00, 0x82, - 0x81, 0x00, 0x00, 0x82, - 0x81, 0x00, 0x00, 0x82, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - - -static uint8_t const _lut_ft[] = { - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x00, - 0xFF, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; #endif // _UC8173_H diff --git a/drivers/gdisp/UC8173/UC8173_waveform_examples.h b/drivers/gdisp/UC8173/UC8173_waveform_examples.h new file mode 100644 index 00000000..e8ac919b --- /dev/null +++ b/drivers/gdisp/UC8173/UC8173_waveform_examples.h @@ -0,0 +1,166 @@ +static uint8_t const _lut_ft[] = { + 0x55,0x55,0x55,0x55,0x55,0xAA,0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5A,0x5A, + 0x5A,0x5A,0x5A,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x5A,0x5A, + 0x5A,0x5A,0x5A,0x5A,0x5A,0x5A,0x5A,0x5A,0x5A,0x5A,0x5A,0x5A,0x00,0xFF,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static uint8_t const _lut_KWvcom_DC_GU[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +static uint8_t const _lut_kw_GU[] = { + 0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80, + 0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80, + 0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static uint8_t const _lut_KWvcom_GC[] = { + 0x55,0x6A,0xA5,0x55,0x55,0x55,0x55,0x55,0x56,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x0C, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +static uint8_t const _lut_kw_GC[] = { + 0x41,0x00,0x00,0x81,0x41,0x00,0x00,0x81,0x41,0x00,0x00,0x81,0x41,0x00,0x00,0x81, + 0x41,0x00,0x00,0x81,0x81,0x00,0x00,0x82,0x81,0x00,0x00,0x82,0x81,0x00,0x00,0x82, + 0x81,0x00,0x00,0x82,0x81,0x00,0x00,0x82,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41, + 0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41, + 0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41, + 0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41, + 0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41, + 0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41, + 0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x42,0x00,0x00,0x41,0x82,0x00,0x00,0x42, + 0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42, + 0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42, + 0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42, + 0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42, + 0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42, + 0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42,0x82,0x00,0x00,0x42, + 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static uint8_t const _lut_KWvcom_DC_A2_240ms[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +static uint8_t const _lut_kw_A2_240ms[] = { + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static uint8_t const _lut_KWvcom_DC_A2_120ms[] = { + 0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +static uint8_t const _lut_kw_A2_120ms[] = { + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; diff --git a/drivers/gdisp/UC8173/board_UC8173_template.h b/drivers/gdisp/UC8173/board_UC8173_template.h index f16205f4..b5fd36fe 100644 --- a/drivers/gdisp/UC8173/board_UC8173_template.h +++ b/drivers/gdisp/UC8173/board_UC8173_template.h @@ -8,9 +8,30 @@ #ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H -static GFXINLINE void init_board(GDisplay* g) +// Define options for this driver +#define UC8173_REVERSEAXIS_Y FALSE +#define UC8173_REVERSEAXIS_X FALSE +#define UC8173_USE_OTP_LUT FALSE /* Use the LUT in the OTP - untested */ +#define UC8173_DEFAULT_MODE 0 /* Which entry in the mode table to start with */ +#define UC8173_CAN_READ FALSE /* Reading the controller chip is supported */ +#define UC8173_VCOM_VOLTAGE -2.80 /* Read this off the sticker on the back of the display or set UC8173_CAN_READ to have the chip read */ +#define UC8171_BORDER 0 /* 0 = Hi-Z, 1 = Black, 2 = White */ + +// Define the waveform table +#include "UC8173_waveform_examples.h" +static UC8173Lut UC8173_ModeTable[] = { + // 32 bytes, 512 bytes, 128 bytes, regal + { _lut_KWvcom_DC_A2_240ms, _lut_kw_A2_240ms, _lut_ft, FALSE }, + { _lut_KWvcom_DC_A2_120ms, _lut_kw_A2_120ms, _lut_ft, FALSE }, + { _lut_KWvcom_DC_GU, _lut_kw_GU, _lut_ft, TRUE }, + { _lut_KWvcom_GC, _lut_kw_GC, _lut_ft, FALSE } + // Add extra lines for other waveforms + }; + +static GFXINLINE bool_t init_board(GDisplay* g) { (void) g; + return TRUE; } static GFXINLINE void post_init_board(GDisplay* g) @@ -24,6 +45,12 @@ static GFXINLINE void setpin_reset(GDisplay* g, bool_t state) (void) state; } +static GFXINLINE bool_t getpin_busy(GDisplay* g) +{ + (void)g; + return FALSE; +} + static GFXINLINE void acquire_bus(GDisplay* g) { (void) g; @@ -46,11 +73,19 @@ static GFXINLINE void write_data(GDisplay* g, uint8_t data) (void) data; } -static GFXINLINE void write_data_burst(GDisplay* g, uint8_t* data, uint16_t length) +static GFXINLINE void write_data_burst(GDisplay* g, uint8_t* data, unsigned length) { (void) g; (void) data; (void) length; } +#if UC8173_CAN_READ + static GFXINLINE uint8_t read_data(GDisplay* g) + { + (void)g; + return 0; + } +#endif + #endif /* _GDISP_LLD_BOARD_H */ diff --git a/drivers/gdisp/UC8173/gdisp_lld_UC8173.c b/drivers/gdisp/UC8173/gdisp_lld_UC8173.c index e65b74fa..88e2761e 100644 --- a/drivers/gdisp/UC8173/gdisp_lld_UC8173.c +++ b/drivers/gdisp/UC8173/gdisp_lld_UC8173.c @@ -12,8 +12,6 @@ #define GDISP_DRIVER_VMT GDISPVMT_UC8173 #include "gdisp_lld_config.h" #include "../../../src/gdisp/gdisp_driver.h" -#include "UC8173.h" -#include "board_UC8173.h" #if defined(GDISP_SCREEN_HEIGHT) || defined(GDISP_SCREEN_HEIGHT) #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT @@ -25,172 +23,198 @@ #undef GDISP_SCREEN_HEIGHT #endif -#define GDISP_SCREEN_HEIGHT 240 -#define GDISP_SCREEN_WIDTH 240 - -#define PRIV(g) ((UC8173_Private*)((g)->priv)) -#define FRAMEBUFFER(g) ((uint8_t *)(PRIV(g)+1)) -#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) - -#if GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_MONO - #define LINE_BYTES (GDISP_SCREEN_WIDTH/8) - #define WRITEBUFCMD DTM4 - #define xyaddr(x, y) (((x)>>3) + ((y) * LINE_BYTES)) - //#define xybit(x, c) ((c) << ((x) & 7)) // This one has the wrong order of the pixels inside the byte - #define xybit(x, c) ((c) << (7-((x) & 7))) -#elif GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_GRAY4 - #define LINE_BYTES (GDISP_SCREEN_WIDTH/4) - #define WRITEBUFCMD DTM2 // NOT SURE THIS IS RIGHT - MAY NEED TO USE DTM0 and then send a refresh??? - #define xyaddr(x, y) (((x)>>2) + ((y) * LINE_BYTES)) - //#define xybit(x, c) ((c) << (((x) & 3)<<1)) // This one has the wrong order of the pixels inside the byte - #define xybit(x, c) ((c) << (6-((x) & 3)<<1)) -#else - #error "UC8173: Unsupported driver color format" -#endif - -typedef struct UC8173_Private { - coord_t flushWindowX; - coord_t flushWindowY; - coord_t flushWindowWidth; - coord_t flushWindowHeight; -} UC8173_Private; - -// This function rounds a given integer up to a specified multiple. Note, multiple must be a power of 2! -static GFXINLINE void _roundUp(coord_t* numToRound, uint8_t multiple) -{ - *numToRound = (*numToRound + multiple - 1) & ~(multiple - 1); -} - -static GFXINLINE void _wait_for_busy_high(GDisplay* g) -{ - while (!getpin_busy(g)); -} - -static GFXINLINE void _wait_for_busy_low(GDisplay* g) -{ - while (getpin_busy(g)); -} - -void _load_lut(GDisplay* g, uint32_t lutRegister, const uint8_t* lut, uint32_t lutCounter) -{ - uint32_t i; +/*------------------ Load the board file ------------------*/ +typedef struct UC8173Lut { + uint8_t const *lutVCOM; // 32 bytes + uint8_t const *lutFW; // 512 bytes + uint8_t const *lutFT; // 128 bytes + bool_t regal; + } UC8173Lut; - write_cmd(g, lutRegister); - for (i = 0; i < lutCounter; i++) { - write_data(g, *lut); - lut++; - } -} +#include "board_UC8173.h" -static void _upload_lut(GDisplay* g) -{ - _load_lut(g, LUT_KWVCOM, _lut_KWvcom_DC_A2_240ms, 32); - _load_lut(g, LUT_KW, _lut_kw_A2_240ms, 512); - _load_lut(g, LUT_FT, _lut_ft, 128); -} +/*------------------ Default UC8173 parameters ------------------*/ +#ifndef UC8173_REVERSEAXIS_Y + #define UC8173_REVERSEAXIS_Y FALSE +#endif +#ifndef UC8173_REVERSEAXIS_X + #define UC8173_REVERSEAXIS_X FALSE +#endif +#ifndef UC8173_DEFAULT_MODE + #define UC8173_DEFAULT_MODE 0 +#endif +#ifndef UC8173_USE_OTP_LUT + #define UC8173_USE_OTP_LUT FALSE +#endif +#ifndef UC8173_CAN_READ + #define UC8173_CAN_READ FALSE +#endif +#ifdef UC8173_VCOM_VOLTAGE + #define UC8173_VCOM_VOLTAGEBYTE (((UC8173_VCOM_VOLTAGE) + 0.1)/-0.05) +#endif +#ifndef UC8171_BORDER + #define UC8171_BORDER 0 /* 0 = Hi-Z, 1 = Black, 2 = White */ +#endif +#ifndef UC8173_INIT_REAL_LUT + #define UC8173_INIT_REAL_LUT TRUE +#endif +#define UC8173_HEIGHT 240 +#define UC8173_WIDTH 240 + +/*------------------ Set FB parameters ------------------*/ +#define FB_REVERSEAXIS_Y UC8173_REVERSEAXIS_Y +#define FB_REVERSEAXIS_X UC8173_REVERSEAXIS_X +#define FB_WIDTH UC8173_WIDTH +#define FB_HEIGHT UC8173_HEIGHT +#define FB_PAGES 1 +#define FB_PIXELORDER_MSB TRUE + +/*------------------ Include Generic FB Code ------------------*/ +// This FB is for 1,2 or 4 bits per pixel packed along the x-axis +#define FB_TYPE_PIXELS (LLDCOLOR_TYPE_BITS/LLDCOLOR_BITS) +#define FB_AXIS_MASK (FB_TYPE_PIXELS-1) +#define FB_LINE_TYPES ((FB_WIDTH+FB_TYPE_PIXELS-1)/FB_TYPE_PIXELS) +#define FB_PAGE_TYPES (FB_LINE_TYPES*FB_HEIGHT) +#define FB_ADDR(fbp, pg, px, py) ((fbp)->fb + ((px)/FB_TYPE_PIXELS + (py)*FB_LINE_TYPES + (pg)*FB_PAGE_TYPES)) +#if FB_PIXELORDER_MSB + #define FB_COLOR(px, py, c) ((c) << ((LLDCOLOR_TYPE_BITS-LLDCOLOR_BITS)-(((px) & FB_AXIS_MASK)<<(LLDCOLOR_BITS-1)))) +#else + #define FB_COLOR(px, py, c) ((c) << (((px) & FB_AXIS_MASK)<<(LLDCOLOR_BITS-1))) +#endif +#define FB_FLUSH_REQUIRED(fbp) ((fbp)->fa0.x < (fbp)->fa1.x) +#define FB_FLUSH_WIDTH(fbp) ((fbp)->fa1.x - (fbp)->fa0.x + 1) +#define FB_FLUSH_HEIGHT(fbp) ((fbp)->fa1.y - (fbp)->fa0.y + 1) +#define FB_FLUSH_ALL(fbp) { (fbp)->fa0.x = (fbp)->fa0.y = 0; (fbp)->fa1.x = FB_WIDTH-1; (fbp)->fa1.y = FB_HEIGHT-1; } +#define FB_FLUSH_NONE(fbp) { (fbp)->fa0.x = FB_WIDTH; (fbp)->fa0.y = FB_HEIGHT; (fbp)->fa1.x = (fbp)->fa1.y = -1; } +#define FB_FLUSH_POINT(fbp, px, py) { \ + if ((px) < (fbp)->fa0.x) (fbp)->fa0.x = (px) & ~FB_AXIS_MASK; \ + if ((px) > (fbp)->fa1.x) (fbp)->fa1.x = (px) | FB_AXIS_MASK; \ + if ((py) < (fbp)->fa0.y) (fbp)->fa0.y = (py); \ + if ((py) > (fbp)->fa1.y) (fbp)->fa1.y = (py); \ + } +#define FB_SETPIXEL(fbp, pg, px, py, c) { \ + LLDCOLOR_TYPE *p, oc; \ + p = FB_ADDR((fbp), (pg), (px), (py)); \ + oc = (*p & ~FB_COLOR((px), (py), LLDCOLOR_MASK())) | FB_COLOR((px), (py), (c)); \ + if (oc != *p) { *p = oc; FB_FLUSH_POINT((fbp), (px), (py)); } \ + } -static void _clear_lut(GDisplay* g) -{ - write_cmd(g, PON); - _wait_for_busy_high(g); +typedef struct FBpriv { + point_t fa0, fa1; + LLDCOLOR_TYPE fb[FB_PAGE_TYPES * FB_PAGES]; + } FBpriv; - _load_lut(g, LUT_KW, _lut_None, 42); - _load_lut(g, LUT_KWVCOM, _lut_None, 42); +/*------------------ UC8173 Driver Code ------------------*/ - write_cmd(g, POF); - _wait_for_busy_low(g); -} +#include "UC8173.h" -#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL - static void _invertFramebuffer(GDisplay* g) - { - uint32_t i; +// UC8173 Inernal Macros & types +typedef struct UC8173_Private { + UC8173Lut *lut; + FBpriv fb; +} UC8173_Private; - for (i = 0; i < LINE_BYTES*GDISP_SCREEN_HEIGHT; i++) { - FRAMEBUFFER(g)[i] = ~(FRAMEBUFFER(g)[i]); - } - - // We should flush these changes to the display controller framebuffer at some point - g->flags |= GDISP_FLG_NEEDFLUSH; - } +#if !UC8173_INIT_REAL_LUT + static uint8_t const UC8173_LUT_None[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00 + }; #endif - + LLDSPEC bool_t gdisp_lld_init(GDisplay* g) { - // Allocate the private area plus the framebuffer - g->priv = gfxAlloc(sizeof(UC8173_Private) + LINE_BYTES*GDISP_SCREEN_HEIGHT); - if (!g->priv) { + UC8173_Private *priv; + + // Allocate the private area + g->priv = gfxAlloc(sizeof(UC8173_Private)); + if (!g->priv) return FALSE; - } + priv = (UC8173_Private *)g->priv; // Initialize the private area - PRIV(g)->flushWindowX = 0; - PRIV(g)->flushWindowY = 0; - PRIV(g)->flushWindowWidth = GDISP_SCREEN_WIDTH; - PRIV(g)->flushWindowHeight = GDISP_SCREEN_HEIGHT; + // As the display is non-volatile we need to ensure a full flush on the first draw + priv->lut = &UC8173_ModeTable[UC8173_DEFAULT_MODE]; + FB_FLUSH_ALL(&priv->fb); // Initialise the board interface - if (!init_board(g)) { + if (!init_board(g)) return FALSE; - } // Hardware reset setpin_reset(g, FALSE); gfxSleepMilliseconds(100); setpin_reset(g, TRUE); - gfxSleepMilliseconds(1000); + gfxSleepMilliseconds(300); // Acquire the bus acquire_bus(g); - // Booster soft-start + // Booster soft-start - Values from example code write_cmd(g, BTST); - write_data(g, 0x17); //0x17 - write_data(g, 0x97); //0x97 - write_data(g, 0x20); //0x20 + write_data(g, 0x17); // data: PhaseA: Bits76=StartupTime [10ms+n*10ms def=0x00], Bits543=Strength, Bits210=MinGDROffTime + write_data(g, 0x97); // data: PhaseB: Bits76=StartupTime [10ms+n*10ms def=0x00], Bits543=Strength, Bits210=MinGDROffTime + write_data(g, 0x20); // data: PhaseC: Bits543=Strength, Bits210=MinGDROffTime [def=0x07] - // Power settings + // Power settings - Values from datasheet default values write_cmd(g, PWR); - write_data(g, 0x03); - write_data(g, 0x00); - write_data(g, 0x2B); //1C 2B - write_data(g, 0x2B); //1C 2B - write_data(g, 0x00); + write_data(g, 0x03); // data: 0x02=Internal VDH/VDL, 0x01=Internal VGH/VGL + write_data(g, 0x00); // data: Always 0x00 + write_data(g, 0x26); // data: 0x00->0x3F VSH Voltage 2.4V -> 11.0V step 0.2V - default=10V (0x26) + write_data(g, 0x26); // data: 0x00->0x3F VSL Voltage 2.4V -> 11.0V step 0.2V - default=10V (0x26) + write_data(g, 0x03); // data: 0x00->0x3F Red Voltage 2.4V -> 11.0V step 0.2V - default= 3V (0x03) // Power-on write_cmd(g, PON); - _wait_for_busy_high(g); + while (!getpin_busy(g)); - // Panel setting register - write_cmd(g, PSR); - write_data(g, 0x0F); //0x0B - write_data(g, 0x86); //0x86 + // Panel setting register - Values from datasheet (OTP untested) + write_cmd(g, PSR); // data: 0x08 + ..., 0x04=Shift Right, 0x02=Booster On, 0x01=Reset Off + write_data(g, 0x0F); + #if UC8173_USE_OTP_LUT + write_cmd(g, 0x86); // data: Always 0x86, write_data=Register LUT, write_cmd=OTP LUT + #else + write_data(g, 0x86); + #endif - // Power-off sequence - write_cmd(g, PFS); + // Power-off sequence - Values from example code + write_cmd(g, PFS); // data: Shutdown frames - 0x00=1, 0x10=2, 0x20=3, 0x30=4 write_data(g, 0x00); - // PLL control - write_cmd(g, LPRD); + // PLL control - Values from example code + write_cmd(g, LPRD); // data: PLL Clock Freq = 1MHz/(n+1) Min=0x04 (=200kHz) write_data(g, 0x25); - // Internal temperature sensor enable - write_cmd(g, TSE); - write_data(g, 0x00); // Use internal temperature sensor + // Internal temperature sensor enable - Values from example code + write_cmd(g, TSE); // data: 0x00=Use internal temperature sensor, 0x80=external, Bits0-4=signed degrees to add eg 0x0F = -1 + write_data(g, 0x00); - // VCOM and data interval settings - write_cmd(g, CDI); - write_data(g, 0xE1); - write_data(g, 0x20); - write_data(g, 0x10); + // VCOM settings - Values from datasheet + write_cmd(g, CDI); // data: 0x80=Border Hi-Z, 0x40=Border Output DC enabled, 0x30=BorderColor, 0x01=Normal/Inverted + #if UC8171_BORDER == 0 + write_data(g, 0x81); + #elif UC8171_BORDER == 1 + write_data(g, 0x41); + #elif UC8171_BORDER == 2 + write_data(g, 0x71); + #else + #error "UC8173: UC8173_BORDER must be 0..2" + #endif + + // More VCOM data - Values from example code + write_data(g, 0x20); // data: 0xX0=Src->VCOM interval (n+1 HSync, Def=0011), 0b0000-00XX=VCOM->Src interval (top 2 bits) + write_data(g, 0x10); // data: 0xXX=VCOM->Src interval (bottom 8 bits) Def=0x18 - // Set display panel resolution + // Set display panel resolution - from datasheet: should always be 240x240 for this chip write_cmd(g, TRES); - write_data(g, 0xEF); - write_data(g, 0x00); - write_data(g, 0xEF); + write_data(g, (UC8173_WIDTH-1)); + write_data(g, ((UC8173_HEIGHT-1)>>8)); + write_data(g, ((UC8173_HEIGHT-1) & 0xFF)); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, GDS); write_data(g, 0xA9); write_data(g, 0xA9); @@ -198,45 +222,72 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) write_data(g, 0xEB); write_data(g, 0x02); - // Auto measure VCOM + // Auto measure VCOM - Values from example code write_cmd(g, AMV); - write_data(g, 0x11); // 5 seconds, enabled - _wait_for_busy_high(g); - - // Get current VCOM value - // write_cmd(g, VV); - // unsigned char vcom_temp = spi_9b_get(); - // vcom_temp = vcom_temp + 4; - // Auto_VCOM = vcom_temp; - - // VCM_DC setting - write_cmd(g, VDCS); - write_data(g, 0x12); // Write vcom_temp here + write_data(g, 0x11); + while (!getpin_busy(g)); + + // Get current VCOM value and write it + #if defined(UC8173_VCOM_VOLTAGEBYTE) + // VCM_DC setting + write_cmd(g, VDCS); + write_data(g, UC8173_VCOM_VOLTAGEBYTE); // was 0x12 in example code = -1.0V + #elif UC8173_CAN_READ + { + uint8_t vc; + + write_cmd(g, VV); + vc = read_data(g); + write_cmd(g, VDCS); + write_data(g, vc); + } + #else + #error "UC8173: Either UC8173_VCOM_VOLTAGE or UC8173_VCOM_VOLTAGEBYTE must be defined or UC8173_CAN_READ must be TRUE" + #endif - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, VBDS); write_data(g, 0x22); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, LVSEL); write_data(g, 0x02); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, GBS); write_data(g, 0x02); write_data(g, 0x02); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, GSS); write_data(g, 0x02); write_data(g, 0x02); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, DF); // For REGAL (???) write_data(g, 0x1F); - // Clear the look-up table - _clear_lut(g); + write_cmd(g, PON); + while (!getpin_busy(g)); + + #if UC8173_INIT_REAL_LUT + // Load the real LUT's + write_cmd(g, LUT_KWVCOM); + write_data_burst(g, priv->lut->lutVCOM, 32); + write_cmd(g, LUT_KW); + write_data_burst(g, priv->lut->lutFW, 512); + write_cmd(g, LUT_FT); + write_data_burst(g, priv->lut->lutFT, 128); + #else + // Clear the LUT's - Values from example code + write_cmd(g, LUT_KW); + write_data_burst(g, UC8173_LUT_None, sizeof(UC8173_LUT_None)); + write_cmd(g, LUT_KWVCOM); + write_data_burst(g, UC8173_LUT_None, sizeof(UC8173_LUT_None)); + #endif + + write_cmd(g, POF); + while (getpin_busy(g)); // Finish Init post_init_board(g); @@ -245,8 +296,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) release_bus(g); // Initialise the GDISP structure - g->g.Width = GDISP_SCREEN_WIDTH; - g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = UC8173_WIDTH; + g->g.Height = UC8173_HEIGHT; g->g.Orientation = GDISP_ROTATE_0; g->g.Powermode = powerOn; g->g.Backlight = 0; @@ -258,64 +309,81 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) #if GDISP_HARDWARE_FLUSH LLDSPEC void gdisp_lld_flush(GDisplay* g) { - coord_t y; + coord_t cy, cx, dx, dy; + LLDCOLOR_TYPE *fb; + UC8173_Private *priv; + + priv = (UC8173_Private *)g->priv; - // Don't flush unless we really need to - if (!(g->flags & GDISP_FLG_NEEDFLUSH)) { + if (!FB_FLUSH_REQUIRED(&priv->fb)) return; - } - - // Round the flushing window width and height up to the next multiple of four - _roundUp(&(PRIV(g)->flushWindowWidth), 4); - _roundUp(&(PRIV(g)->flushWindowWidth), 4); + #if 0 + FB_FLUSH_ALL(&priv->fb); + #endif + // Acquire the bus to communicate with the display controller acquire_bus(g); // Upload the new temperature LUT - _upload_lut(g); + write_cmd(g, LUT_KWVCOM); + write_data_burst(g, priv->lut->lutVCOM, 32); + write_cmd(g, LUT_KW); + write_data_burst(g, priv->lut->lutFW, 512); + write_cmd(g, LUT_FT); + write_data_burst(g, priv->lut->lutFT, 128); + + // Calculate the width, height + cx = FB_FLUSH_WIDTH(&priv->fb); + cy = FB_FLUSH_HEIGHT(&priv->fb); // Setup the window + // Datasheet says x,y,w,h but in practice it needs to be x,y,w-1,h-1 write_cmd(g, DTMW); - write_data(g, (uint8_t)((PRIV(g)->flushWindowX >> 0) & 0xFF)); - write_data(g, (uint8_t)((PRIV(g)->flushWindowY >> 8) & 0x03)); - write_data(g, (uint8_t)((PRIV(g)->flushWindowY >> 0) & 0xFF)); - write_data(g, (uint8_t)((((PRIV(g)->flushWindowWidth)-1) >> 0) & 0xFF)); - write_data(g, (uint8_t)((((PRIV(g)->flushWindowHeight)-1) >> 8) & 0x03)); - write_data(g, (uint8_t)((((PRIV(g)->flushWindowHeight)-1) >> 0) & 0xFF)); - - // Dump our framebuffer - // Note: The display controller doesn't allow changing the vertical scanning direction - // so we have to manually send the lines "the other way around" here. - write_cmd(g, WRITEBUFCMD); - for (y = GDISP_SCREEN_HEIGHT-1; y >= 0; y--) { - write_data_burst(g, FRAMEBUFFER(g)+y*LINE_BYTES, LINE_BYTES); - } + write_data(g, (uint8_t)((priv->fb.fa0.x >> 0) & 0xFF)); + write_data(g, (uint8_t)((priv->fb.fa0.y >> 8) & 0x03)); + write_data(g, (uint8_t)((priv->fb.fa0.y >> 0) & 0xFF)); + write_data(g, (uint8_t)(((cx-1) >> 0) & 0xFF)); + write_data(g, (uint8_t)(((cy-1) >> 8) & 0x03)); + write_data(g, (uint8_t)(((cy-1) >> 0) & 0xFF)); + + // Transfer the buffer + #if GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_MONO + write_cmd(g, DTM4); + #elif GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_GRAY4 + write_cmd(g, DTM2); + #else + #error "UC8173: Unsupported driver color format" + #endif + dx = (cx+FB_TYPE_PIXELS-1)/FB_TYPE_PIXELS * (LLDCOLOR_TYPE_BITS/8); + for (fb = FB_ADDR(&priv->fb, 0, priv->fb.fa0.x, priv->fb.fa0.y), dy = cy; dy; dy--, fb += FB_LINE_TYPES) + write_data_burst(g, (uint8_t *)fb, dx); // Power-up the DC/DC converter to update the display panel write_cmd(g, PON); - _wait_for_busy_high(g); + while (!getpin_busy(g)); // Refresh the panel contents - write_cmd(g, DRF); - write_data(g, 0x00); // Enable REGAL function - write_data(g, 0x00); - write_data(g, 0x00); - write_data(g, 0x00); - write_data(g, 0xEF); - write_data(g, 0x00); - write_data(g, 0xEF); - _wait_for_busy_high(g); - - // Power-down the DC/DC converter to make all the low-power pussys happy + // Datasheet says x,y,w,h but in practice it needs to be x,y,w-1,h-1 + write_cmd(g, DRF); // data: Partial Scan = 0x10, REGAL = 0x08, VCOM_DoNothing = 0x04 (GC4/A2 = 0x00, GU4 = 0x08) + write_data(g, (priv->lut->regal ? 0x08 : 0x00)); + write_data(g, (uint8_t)((priv->fb.fa0.x >> 0) & 0xFF)); + write_data(g, (uint8_t)((priv->fb.fa0.y >> 8) & 0x03)); + write_data(g, (uint8_t)((priv->fb.fa0.y >> 0) & 0xFF)); + write_data(g, (uint8_t)(((cx-1) >> 0) & 0xFF)); + write_data(g, (uint8_t)(((cy-1) >> 8) & 0x03)); + write_data(g, (uint8_t)(((cy-1) >> 0) & 0xFF)); + while (!getpin_busy(g)); + + // Power-down the DC/DC converter write_cmd(g, POF); - _wait_for_busy_low(g); + while (getpin_busy(g)); - // Release the bus again + // Release the bus release_bus(g); - // Clear the 'need-flushing' flag - g->flags &=~ GDISP_FLG_NEEDFLUSH; + // Mark as flushed + FB_FLUSH_NONE(&priv->fb); } #endif @@ -323,70 +391,134 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) LLDSPEC void gdisp_lld_draw_pixel(GDisplay* g) { coord_t x, y; - LLDCOLOR_TYPE *p; + UC8173_Private *priv; + + priv = (UC8173_Private *)g->priv; // Handle the different possible orientations - 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 = GDISP_SCREEN_HEIGHT-1 - g->p.x; - break; - case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; - y = GDISP_SCREEN_HEIGHT-1 - g->p.y; - break; - case GDISP_ROTATE_270: - x = GDISP_SCREEN_WIDTH-1 - g->p.y; - y = g->p.x; - break; - } + #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + #if FB_REVERSEAXIS_X + x = FB_WIDTH-1 - g->p.x; + #else + x = g->p.x; + #endif + #if FB_REVERSEAXIS_Y + y = FB_HEIGHT-1 - g->p.y; + #else + y = g->p.y; + #endif + break; + case GDISP_ROTATE_90: + #if FB_REVERSEAXIS_X + x = FB_WIDTH-1 - g->p.y; + #else + x = g->p.y; + #endif + #if FB_REVERSEAXIS_Y + y = g->p.x; + #else + y = FB_HEIGHT-1 - g->p.x; + #endif + break; + case GDISP_ROTATE_180: + #if FB_REVERSEAXIS_X + x = g->p.x; + #else + x = FB_WIDTH-1 - g->p.x; + #endif + #if FB_REVERSEAXIS_Y + y = g->p.y; + #else + y = FB_HEIGHT-1 - g->p.y; + #endif + break; + case GDISP_ROTATE_270: + #if FB_REVERSEAXIS_X + x = g->p.y; + #else + x = FB_WIDTH-1 - g->p.y; + #endif + #if FB_REVERSEAXIS_Y + y = FB_HEIGHT-1 - g->p.x; + #else + y = g->p.x; + #endif + break; + } + #else + #if FB_REVERSEAXIS_X + x = FB_WIDTH-1 - g->p.x; + #else + x = g->p.x; + #endif + #if FB_REVERSEAXIS_Y + y = FB_HEIGHT-1 - g->p.y; + #else + y = g->p.y; + #endif + #endif // Modify the framebuffer content - p = &FRAMEBUFFER(g)[xyaddr(x,y)]; - *p &=~ xybit(x, LLDCOLOR_MASK()); - *p |= xybit(x, gdispColor2Native(g->p.color)); - -// ToDo -// There appears to be an issue in the silicone, still talking to the manufacturer about this one. Update will follow! -#if 0 - // Update the flush window region - if (g->flags & GDISP_FLG_NEEDFLUSH) { - if (x < PRIV(g)->flushWindowX) - PRIV(g)->flushWindowX = x; - if (y < PRIV(g)->flushWindowY) - PRIV(g)->flushWindowY = y; - if (x > PRIV(g)->flushWindowX + PRIV(g)->flushWindowWidth) - PRIV(g)->flushWindowWidth = - } else { - PRIV(g)->flushWindowX = x; - PRIV(g)->flushWindowY = y; - PRIV(g)->flushWindowWidth = 1; - PRIV(g)->flushWindowHeight = 1; - } -#else - PRIV(g)->flushWindowX = 0; - PRIV(g)->flushWindowY = 0; - PRIV(g)->flushWindowWidth = GDISP_SCREEN_WIDTH; - PRIV(g)->flushWindowHeight = GDISP_SCREEN_HEIGHT; -#endif - - // We should flush these changes to the display controller framebuffer at some point - g->flags |= GDISP_FLG_NEEDFLUSH; + FB_SETPIXEL(&priv->fb, 0, x, y, gdispColor2Native(g->p.color)); } #endif #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL LLDSPEC void gdisp_lld_control(GDisplay* g) { + UC8173_Private *priv; + + priv = (UC8173_Private *)g->priv; + switch(g->p.x) { + + // Custom gdispControl() to invert the framebuffer case GDISP_CONTROL_INVERT: - _invertFramebuffer(g); + { + unsigned i; + LLDCOLOR_TYPE *fb; + + // Invert the framebuffer + for (fb = priv->fb.fb, i = FB_PAGE_TYPES; i ; i--, fb++) + fb[0] = ~fb[0]; + + // We should flush these changes to the display controller framebuffer at some point + FB_FLUSH_ALL(&priv->fb); + } break; + // Custom gdispControl() to set which EINK Mode (waveform) to use + case GDISP_CONTROL_SETMODE: + if ((unsigned)g->p.ptr < sizeof(UC8173_ModeTable)/sizeof(UC8173_ModeTable[0])) + priv->lut = &UC8173_ModeTable[(unsigned)g->p.ptr]; + break; + + // Custom gdispControl() to set the EINK border + case GDISP_CONTROL_SETBORDER: + if ((unsigned)g->p.ptr > 2) + break; + acquire_bus(g); + write_cmd(g, PON); + while (!getpin_busy(g)); + write_cmd(g, CDI); + switch((unsigned)g->p.ptr) { + case 0: + write_data(g, 0x81); // Border Hi-Z + break; + case 1: + write_data(g, 0x41); // Border Black + break; + case 2: + write_data(g, 0x71); // Border White + break; + } + write_cmd(g, POF); + while (getpin_busy(g)); + release_bus(g); + break; + default: break; } diff --git a/drivers/gdisp/UC8173/gdisp_lld_config.h b/drivers/gdisp/UC8173/gdisp_lld_config.h index e10928eb..1d9146a2 100644 --- a/drivers/gdisp/UC8173/gdisp_lld_config.h +++ b/drivers/gdisp/UC8173/gdisp_lld_config.h @@ -16,13 +16,16 @@ #define GDISP_HARDWARE_FLUSH TRUE #define GDISP_HARDWARE_DRAWPIXEL TRUE -#define GDISP_HARDWARE_PIXELREAD FALSE +//#define GDISP_HARDWARE_PIXELREAD TRUE - not implemented yet #define GDISP_HARDWARE_CONTROL TRUE #define GDISP_HARDWARE_FILLS FALSE #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO +//#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY4 #define GDISP_CONTROL_INVERT (GDISP_CONTROL_LLD+0) +#define GDISP_CONTROL_SETMODE (GDISP_CONTROL_LLD+1) /* Parameter: 0..n (as defined by the board file) */ +#define GDISP_CONTROL_SETBORDER (GDISP_CONTROL_LLD+2) /* Parameter: 0=Border Hi-Z, 1=Border Black, 2=Border White */ #endif /* GFX_USE_GDISP */ diff --git a/drivers/gdisp/readme.txt b/drivers/gdisp/readme.txt index cc0fd724..f91922a6 100644 --- a/drivers/gdisp/readme.txt +++ b/drivers/gdisp/readme.txt @@ -35,6 +35,7 @@ TestStub - NULL driver just to test compile TLS8204 - Small monochrome LCD
UC8173 - E-Ink display driver
UC1601s - Small (64x132) monochrome LCD
+UC1610 - Small (78x64 or 160x104) 4 level grayscale LCD
QImage - Driver that allows rendering into a QImage object (of the Qt framework)
uGFXnet - Remote Network display (in drivers/multiple/uGFXnet directory)
Win32 - Microsoft Windows (in drivers/multiple/Win32 directory)
diff --git a/gfxconf.example.h b/gfxconf.example.h index b278ed70..e32dd19f 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -36,7 +36,9 @@ //#define GFX_USE_OS_RAWRTOS FALSE //#define GFX_USE_OS_ARDUINO FALSE //#define GFX_USE_OS_KEIL FALSE +//#define GFX_USE_OS_RTX5 FALSE //#define GFX_USE_OS_CMSIS FALSE +//#define GFX_USE_OS_CMSIS2 FALSE //#define GFX_USE_OS_RAW32 FALSE //#define GFX_USE_OS_NIOS FALSE //#define GFX_USE_OS_QT FALSE diff --git a/src/gos/gos.h b/src/gos/gos.h index ddca0d94..dedfcdda 100644 --- a/src/gos/gos.h +++ b/src/gos/gos.h @@ -403,27 +403,6 @@ void gfxSemSignalI(gfxSem *psem); /** - * @brief Get the current semaphore count - * @return The current semaphore count - * - * @param[in] psem A pointer to the semaphore - * - * @api - */ - semcount_t gfxSemCounter(gfxSem *psem); - - /** - * @brief Get the current semaphore count - * @return The current semaphore count - * - * @param[in] psem A pointer to the semaphore - * - * @iclass - * @api - */ - semcount_t gfxSemCounterI(gfxSem *psem); - - /** * @brief Start a new thread. * @return Returns a thread handle if the thread was started, NULL on an error * @@ -497,8 +476,12 @@ #include "gos_arduino.h" #elif GFX_USE_OS_CMSIS #include "gos_cmsis.h" +#elif GFX_USE_OS_CMSIS2 + #include "gos_cmsis2.h" #elif GFX_USE_OS_KEIL #include "gos_keil.h" +#elif GFX_USE_OS_RTX5 + #include "gos_rtx5.h" #elif GFX_USE_OS_NIOS #include "gos_nios.h" #elif GFX_USE_OS_QT diff --git a/src/gos/gos_chibios.c b/src/gos/gos_chibios.c index d02127ab..8bad8ed6 100644 --- a/src/gos/gos_chibios.c +++ b/src/gos/gos_chibios.c @@ -139,8 +139,13 @@ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) bool_t gfxSemWaitI(gfxSem *psem) { - if (chSemGetCounterI(&psem->sem) <= 0) - return FALSE; + #if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3) + if (psem->sem.s_cnt <= 0) + return GFalse; + #elif (CH_KERNEL_MAJOR == 4) + if (psem->sem.cnt <= 0) + return GFalse; + #endif chSemFastWaitI(&psem->sem); return TRUE; } @@ -149,8 +154,13 @@ void gfxSemSignal(gfxSem *psem) { chSysLock(); - if (gfxSemCounterI(psem) < psem->limit) - chSemSignalI(&psem->sem); + #if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3) + if (psem->sem.s_cnt < psem->limit) + chSemSignalI(&psem->sem); + #elif (CH_KERNEL_MAJOR == 4) + if (psem->sem.cnt < psem->limit) + chSemSignalI(&psem->sem); + #endif chSchRescheduleS(); chSysUnlock(); @@ -158,19 +168,24 @@ void gfxSemSignal(gfxSem *psem) void gfxSemSignalI(gfxSem *psem) { - if (gfxSemCounterI(psem) < psem->limit) - chSemSignalI(&psem->sem); + #if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3) + if (psem->sem.s_cnt < psem->limit) + chSemSignalI(&psem->sem); + #elif (CH_KERNEL_MAJOR == 4) + if (psem->sem.cnt < psem->limit) + chSemSignalI(&psem->sem); + #endif } gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param) { if (!stackarea) { if (!stacksz) stacksz = 256; -#if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3) - return chThdCreateFromHeap(0, stacksz, prio, (tfunc_t)fn, param); -#elif CH_KERNEL_MAJOR == 4 - return chThdCreateFromHeap(0, stacksz, "ugfx", prio, (tfunc_t)fn, param); -#endif + #if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3) + return chThdCreateFromHeap(0, stacksz, prio, (tfunc_t)fn, param); + #elif CH_KERNEL_MAJOR == 4 + return chThdCreateFromHeap(0, stacksz, "ugfx", prio, (tfunc_t)fn, param); + #endif } if (!stacksz) diff --git a/src/gos/gos_chibios.h b/src/gos/gos_chibios.h index c3fc9d36..aedfb492 100644 --- a/src/gos/gos_chibios.h +++ b/src/gos/gos_chibios.h @@ -120,13 +120,6 @@ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); bool_t gfxSemWaitI(gfxSem *psem); void gfxSemSignal(gfxSem *psem); void gfxSemSignalI(gfxSem *psem); -#if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3) -#define gfxSemCounterI(psem) ((psem)->sem.s_cnt) -#define gfxSemCounter(psem) ((psem)->sem.s_cnt) -#elif (CH_KERNEL_MAJOR == 4) -#define gfxSemCounterI(psem) ((psem)->sem.cnt) -#define gfxSemCounter(psem) ((psem)->sem.cnt) -#endif gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); #define gfxThreadWait(thread) chThdWait(thread) #define gfxThreadMe() chThdSelf() diff --git a/src/gos/gos_cmsis2.c b/src/gos/gos_cmsis2.c new file mode 100644 index 00000000..abbea6b2 --- /dev/null +++ b/src/gos/gos_cmsis2.c @@ -0,0 +1,110 @@ +/* + * 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" +#include <string.h> + +#if GFX_USE_OS_CMSIS2 + +#if !GFX_OS_NO_INIT && !GFX_OS_CALL_UGFXMAIN + #error "GOS: Either GFX_OS_NO_INIT or GFX_OS_CALL_UGFXMAIN must be defined for CMSIS V2" +#endif + +void _gosHeapInit(void); + +void _gosInit(void) +{ + #if GFX_OS_NO_INIT && !GFX_OS_INIT_NO_WARNING + #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT + #warning "GOS: Operating System initialization has been turned off. Make sure you call osKernelInitialize()." + #elif GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_MACRO + COMPILER_WARNING("GOS: Operating System initialization has been turned off. Make sure you call osKernelInitialize().") + #endif + #endif + + // Set up the heap allocator + _gosHeapInit(); +} + +#if !GFX_OS_NO_INIT && GFX_OS_CALL_UGFXMAIN + static DECLARE_THREAD_FUNCTION(startUGFX_CMSIS2, p) { + (void) p; + uGFXMain(); + } +#endif +void _gosPostInit(void) +{ + #if !GFX_OS_NO_INIT && GFX_OS_CALL_UGFXMAIN + switch(osKernelGetState()) { + case osKernelInactive: + osKernelInitialize(); + /* Fall Through */ + case osKernelReady: + gfxThreadCreate(0, GFX_OS_UGFXMAIN_STACKSIZE, NORMAL_PRIORITY, startUGFX_CMSIS2, 0); + osKernelStart(); + gfxHalt("Unable to start CMSIS V2 scheduler. Out of memory?"); + break; + default: + gfxThreadCreate(0, GFX_OS_UGFXMAIN_STACKSIZE, NORMAL_PRIORITY, startUGFX_CMSIS2, 0); + break; + } + #endif +} + +void _gosDeinit(void) +{ +} + +void gfxMutexInit(gfxMutex* pmutex) +{ + *pmutex = osMutexNew(NULL); +} + +void gfxSemInit(gfxSem* psem, semcount_t val, semcount_t limit) +{ + *pmutex = osSemaphoreNew(limit, val, NULL); +} + +bool_t gfxSemWait(gfxSem* psem, delaytime_t ms) +{ + if (osSemaphoreAcquire(*psem, gfxMillisecondsToTicks(ms)) == osOK) + return TRUE; + return FALSE; +} + +gfxThreadHandle gfxThreadCreate(void* stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void* param) +{ + osThreadAttr_t def; + + (void)stackarea; + + memset(&def, 0, sizeof(def)); + def.name = "uGFX"; + def.attr_bits = osThreadDetached; // osThreadJoinable + def.stack_mem = 0; + def.stack_size = stacksz; + def.priority = prio; + //def.tz_module = ????; + + return osThreadNew((osThreadFunc_t)fn, param, &def); +} + +threadreturn_t gfxThreadWait(gfxThreadHandle thread) { + while(1) { + switch(osThreadGetState(thread)) { + case osThreadReady: + case osThreadRunning: + case osThreadBlocked: + gfxYield(); + break; + default: + return; + } + } +} + +#endif /* GFX_USE_OS_CMSIS2 */ diff --git a/src/gos/gos_cmsis2.h b/src/gos/gos_cmsis2.h new file mode 100644 index 00000000..06d5da04 --- /dev/null +++ b/src/gos/gos_cmsis2.h @@ -0,0 +1,99 @@ +/* + * 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/gos/gos_cmsis2.h + * @brief GOS - Operating System Support header file for CMSIS 2.0 RTOS. + */ + +#ifndef _GOS_CMSIS2_H +#define _GOS_CMSIS2_H + +#if GFX_USE_OS_CMSIS2 + +#include <stdbool.h> +#include "cmsis_os2.h" + +#ifndef GFX_OS_HEAP_SIZE + #define GFX_OS_HEAP_SIZE 10240 +#endif + +/*===========================================================================*/ +/* Type definitions */ +/*===========================================================================*/ + +typedef bool bool_t; + +#define TIME_IMMEDIATE 0 +#define TIME_INFINITE osWaitForever +typedef uint32_t delaytime_t; +typedef uint32_t systemticks_t; +typedef uint16_t semcount_t; +typedef void threadreturn_t; +typedef osPriority_t threadpriority_t; + +#define MAX_SEMAPHORE_COUNT osFeature_Semaphore +#define LOW_PRIORITY osPriorityLow +#define NORMAL_PRIORITY osPriorityNormal +#define HIGH_PRIORITY osPriorityHigh + +typedef osSemaphoreId_t gfxSem; + +typedef osMutexId_t gfxMutex; + +typedef osThreadId_t gfxThreadHandle; + +#define DECLARE_THREAD_STACK(name, sz) uint8_t name[1]; // Some compilers don't allow zero sized arrays. Let's waste one byte +#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void* param) +#define THREAD_RETURN(retval) + +/*===========================================================================*/ +/* Function declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define gfxExit() os_error(0) +#define gfxHalt(msg) os_error(1) +#define gfxSystemTicks() osKernelGetSysTimerCount() +#define gfxMillisecondsToTicks(ms) (1000*(ms)/osKernelGetTickFreq()) +#define gfxSystemLock() osKernelLock() +#define gfxSystemUnlock() osKernelUnlock() +#define gfxSleepMilliseconds(ms) osDelay(ms) + +void gfxMutexInit(gfxMutex* pmutex); +#define gfxMutexDestroy(pmutex) osMutexDelete(*(pmutex)) +#define gfxMutexEnter(pmutex) osMutexAcquire(*(pmutex), TIME_INFINITE) +#define gfxMutexExit(pmutex) osMutexRelease(*(pmutex)) + +void gfxSemInit(gfxSem* psem, semcount_t val, semcount_t limit); +#define gfxSemDestroy(psem) osSemaphoreDelete(*(psem)) +bool_t gfxSemWait(gfxSem* psem, delaytime_t ms); +#define gfxSemWaitI(psem) gfxSemWait((psem), 0) +#define gfxSemSignal(psem) osSemaphoreRelease(*(psem)) +#define gfxSemSignalI(psem) osSemaphoreRelease(*(psem)) + +gfxThreadHandle gfxThreadCreate(void* stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void* param); +#define gfxYield() osThreadYield() +#define gfxThreadMe() osThreadGetId() +#define gfxThreadClose(thread) {} + +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Use the generic heap handling */ +/*===========================================================================*/ + +#define GOS_NEED_X_HEAP TRUE +#include "gos_x_heap.h" + +#endif /* GFX_USE_OS_CMSIS */ +#endif /* _GOS_CMSIS_H */ diff --git a/src/gos/gos_ecos.c b/src/gos/gos_ecos.c index f7e557ac..a55773d9 100644 --- a/src/gos/gos_ecos.c +++ b/src/gos/gos_ecos.c @@ -84,7 +84,7 @@ void gfxSemSignal(gfxSem *psem) cyg_semaphore_post(&psem->sem); else { cyg_scheduler_lock(); - if (gfxSemCounterI(psem) < psem->limit) + if (cyg_semaphore_peek(&psem->sem, &cnt) < psem->limit) cyg_semaphore_post(&psem->sem); cyg_scheduler_unlock(); } @@ -92,17 +92,10 @@ void gfxSemSignal(gfxSem *psem) void gfxSemSignalI(gfxSem *psem) { - if (psem->limit == MAX_SEMAPHORE_COUNT || gfxSemCounterI(psem) < psem->limit) + if (psem->limit == MAX_SEMAPHORE_COUNT || cyg_semaphore_peek(&psem->sem, &cnt) < psem->limit) cyg_semaphore_post(&psem->sem); } -semcount_t gfxSemCounterI(gfxSem *psem) { - semcount_t cnt; - - cyg_semaphore_peek(&psem->sem, &cnt); - return cnt; -} - gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param) { gfxThreadHandle th; diff --git a/src/gos/gos_ecos.h b/src/gos/gos_ecos.h index 6aa55a3a..0e438fb0 100644 --- a/src/gos/gos_ecos.h +++ b/src/gos/gos_ecos.h @@ -91,8 +91,6 @@ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); bool_t gfxSemWaitI(gfxSem *psem); void gfxSemSignal(gfxSem *psem); void gfxSemSignalI(gfxSem *psem); -semcount_t gfxSemCounterI(gfxSem *psem); -#define gfxSemCounter(psem) gfxSemCounterI(psem) gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); #define gfxThreadWait(thread) NOTIMPLEMENTED_YET diff --git a/src/gos/gos_linux.c b/src/gos/gos_linux.c index dac3838f..43371443 100644 --- a/src/gos/gos_linux.c +++ b/src/gos/gos_linux.c @@ -165,15 +165,12 @@ threadreturn_t gfxThreadWait(gfxThreadHandle thread) { } } void gfxSemSignal(gfxSem *pSem) { - if (gfxSemCounter(pSem) < pSem->max) - sem_post(&pSem->sem); - } - semcount_t gfxSemCounter(gfxSem *pSem) { int res; res = 0; sem_getvalue(&pSem->sem, &res); - return res; + if (res < pSem->max) + sem_post(&pSem->sem); } #else void gfxSemInit(gfxSem *pSem, semcount_t val, semcount_t limit) { @@ -239,17 +236,6 @@ threadreturn_t gfxThreadWait(gfxThreadHandle thread) { pthread_mutex_unlock(&pSem->mtx); } - semcount_t gfxSemCounter(gfxSem *pSem) { - semcount_t res; - - // The locking is really only required if obtaining the count is a divisible operation - // which it might be on a 8/16 bit processor with a 32 bit semaphore count. - pthread_mutex_lock(&pSem->mtx); - res = pSem->cnt; - pthread_mutex_unlock(&pSem->mtx); - - return res; - } #endif // GFX_USE_POSIX_SEMAPHORES #endif /* GFX_USE_OS_LINUX */ diff --git a/src/gos/gos_linux.h b/src/gos/gos_linux.h index fe406cb6..b9bfe82e 100644 --- a/src/gos/gos_linux.h +++ b/src/gos/gos_linux.h @@ -65,7 +65,6 @@ typedef pthread_mutex_t gfxMutex; sem_t sem; semcount_t max; } gfxSem; - #define gfxSemCounterI(psem) gfxSemCounter(psem) #else typedef struct gfxSem { pthread_mutex_t mtx; @@ -73,7 +72,6 @@ typedef pthread_mutex_t gfxMutex; semcount_t cnt; semcount_t max; } gfxSem; - #define gfxSemCounterI(psem) ((psem)->cnt) #endif /*===========================================================================*/ @@ -95,7 +93,6 @@ void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit); void gfxSemDestroy(gfxSem *psem); bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); void gfxSemSignal(gfxSem *psem); -semcount_t gfxSemCounter(gfxSem *pSem); gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); threadreturn_t gfxThreadWait(gfxThreadHandle thread); diff --git a/src/gos/gos_options.h b/src/gos/gos_options.h index e8ce12e7..1c6dc8b1 100644 --- a/src/gos/gos_options.h +++ b/src/gos/gos_options.h @@ -91,13 +91,27 @@ #define GFX_USE_OS_CMSIS FALSE #endif /** - * @brief Use Keil CMSIS + * @brief Use CMSIS2 RTOS compatible OS + * @details Defaults to FALSE + */ + #ifndef GFX_USE_OS_CMSIS2 + #define GFX_USE_OS_CMSIS2 FALSE + #endif + /** + * @brief Use Keil CMSIS 1.x (RTOS, RTX4) * @details Defaults to FALSE */ #ifndef GFX_USE_OS_KEIL #define GFX_USE_OS_KEIL FALSE #endif /** + * @brief Use Keil RTX5 + * @details Defaults to FALSE + */ + #ifndef GFX_USE_OS_RTX5 + #define GFX_USE_OS_RTX5 FALSE + #endif + /** * @brief Use NIOS-II * @details Defaults to FALSE */ diff --git a/src/gos/gos_osx.c b/src/gos/gos_osx.c index f06685d7..56d64d98 100644 --- a/src/gos/gos_osx.c +++ b/src/gos/gos_osx.c @@ -180,15 +180,4 @@ void gfxSemSignal(gfxSem *pSem) { pthread_mutex_unlock(&pSem->mtx); } -semcount_t gfxSemCounter(gfxSem *pSem) { - semcount_t res; - - // The locking is really only required if obtaining the count is a divisible operation - // which it might be on a 8/16 bit processor with a 32 bit semaphore count. - pthread_mutex_lock(&pSem->mtx); - res = pSem->cnt; - pthread_mutex_unlock(&pSem->mtx); - return res; -} - #endif /* GFX_USE_OS_OSX */ diff --git a/src/gos/gos_osx.h b/src/gos/gos_osx.h index 9a8e10d9..94c67eab 100644 --- a/src/gos/gos_osx.h +++ b/src/gos/gos_osx.h @@ -44,7 +44,6 @@ typedef pthread_mutex_t gfxMutex; #define gfxMutexExit(pmtx) pthread_mutex_unlock(pmtx) #define gfxSemWaitI(psem) gfxSemWait(psem, TIME_IMMEDIATE) #define gfxSemSignalI(psem) gfxSemSignal(psem) -#define gfxSemCounterI(pSem) ((pSem)->cnt) #define TIME_IMMEDIATE 0 #define TIME_INFINITE ((delaytime_t)-1) @@ -78,7 +77,6 @@ void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit); void gfxSemDestroy(gfxSem *psem); bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); void gfxSemSignal(gfxSem *psem); -semcount_t gfxSemCounter(gfxSem *pSem); gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); threadreturn_t gfxThreadWait(gfxThreadHandle thread); diff --git a/src/gos/gos_qt.cpp b/src/gos/gos_qt.cpp index 422f1535..e7480dd2 100644 --- a/src/gos/gos_qt.cpp +++ b/src/gos/gos_qt.cpp @@ -178,16 +178,6 @@ void gfxSemSignalI(gfxSem *psem) static_cast<QSemaphore*>(*psem)->release(1); } -semcount_t gfxSemCounter(gfxSem *psem) -{ - return static_cast<QSemaphore*>(*psem)->available(); -} - -semcount_t gfxSemCounterI(gfxSem *psem) -{ - return static_cast<QSemaphore*>(*psem)->available(); -} - gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param) { Q_UNUSED(stackarea) diff --git a/src/gos/gos_qt.h b/src/gos/gos_qt.h index 9986d7f2..45d743f5 100644 --- a/src/gos/gos_qt.h +++ b/src/gos/gos_qt.h @@ -63,8 +63,6 @@ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); bool_t gfxSemWaitI(gfxSem *psem); void gfxSemSignal(gfxSem *psem); void gfxSemSignalI(gfxSem *psem); -semcount_t gfxSemCounter(gfxSem *psem); -semcount_t gfxSemCounterI(gfxSem *psem); gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); threadreturn_t gfxThreadWait(gfxThreadHandle thread); gfxThreadHandle gfxThreadMe(void); diff --git a/src/gos/gos_rawrtos.h b/src/gos/gos_rawrtos.h index e7778d15..d1026c9d 100644 --- a/src/gos/gos_rawrtos.h +++ b/src/gos/gos_rawrtos.h @@ -47,7 +47,6 @@ typedef RAW_TASK_OBJ* gfxThreadHandle; #define gfxSemDestroy(psem) raw_semaphore_delete(psem) #define gfxSemSignal(psem) raw_semaphore_put((psem)) #define gfxSemSignalI(psem) raw_semaphore_put_all((psem)) -#define gfxSemCounterI(psem) ((psem)->count) #define gfxThreadMe() {(unsigned int)raw_task_identify()} #define gfxThreadClose(thread) {} diff --git a/src/gos/gos_rtx5.h b/src/gos/gos_rtx5.h new file mode 100644 index 00000000..b07a2164 --- /dev/null +++ b/src/gos/gos_rtx5.h @@ -0,0 +1,32 @@ +/* + * 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/gos/gos_rtx5.h + * @brief GOS - Operating System Support header file for Keil RTX + */ + +#ifndef _GOS_RTX5_H +#define _GOS_RTX5_H + +#if GFX_USE_OS_RTX5 + +/* + * Keil RTX uses the CMSIS RTOS interface. Therefore, just use the CMSIS2 RTOS port + */ + +// Disable KEIL to avoid error: "GOS: More than one operation system has been defined as TRUE." +#undef GFX_USE_OS_RTX5 +#define GFX_USE_OS_RTX5 FALSE + +// Enable generic CMSIS RTOS implementation +#undef GFX_USE_OS_CMSIS2 +#define GFX_USE_OS_CMSIS2 TRUE +#include "gos_cmsis2.h" + +#endif /* GFX_USE_OS_RTX5 */ +#endif /* _GOS_RTX5_H */ diff --git a/src/gos/gos_rules.h b/src/gos/gos_rules.h index 6779045d..08de1f3f 100644 --- a/src/gos/gos_rules.h +++ b/src/gos/gos_rules.h @@ -16,11 +16,11 @@ #ifndef _GOS_RULES_H #define _GOS_RULES_H -#if !GFX_USE_OS_CHIBIOS && !GFX_USE_OS_WIN32 && !GFX_USE_OS_LINUX && !GFX_USE_OS_OSX && !GFX_USE_OS_RAW32 && !GFX_USE_OS_FREERTOS && !GFX_USE_OS_ECOS && !GFX_USE_OS_RAWRTOS && !GFX_USE_OS_ARDUINO && !GFX_USE_OS_CMSIS && !GFX_USE_OS_KEIL && !GFX_USE_OS_NIOS && !GFX_USE_OS_QT +#if !GFX_USE_OS_CHIBIOS && !GFX_USE_OS_WIN32 && !GFX_USE_OS_LINUX && !GFX_USE_OS_OSX && !GFX_USE_OS_RAW32 && !GFX_USE_OS_FREERTOS && !GFX_USE_OS_ECOS && !GFX_USE_OS_RAWRTOS && !GFX_USE_OS_ARDUINO && !GFX_USE_OS_CMSIS && !GFX_USE_OS_CMSIS2 && !GFX_USE_OS_KEIL && !GFX_USE_OS_RTX5 && !GFX_USE_OS_NIOS && !GFX_USE_OS_QT #error "GOS: No operating system has been defined." #endif -#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 + GFX_USE_OS_FREERTOS + GFX_USE_OS_ECOS + GFX_USE_OS_RAWRTOS + GFX_USE_OS_ARDUINO + GFX_USE_OS_CMSIS + GFX_USE_OS_KEIL + GFX_USE_OS_NIOS + GFX_USE_OS_QT != 1 * TRUE +#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 + GFX_USE_OS_FREERTOS + GFX_USE_OS_ECOS + GFX_USE_OS_RAWRTOS + GFX_USE_OS_ARDUINO + GFX_USE_OS_CMSIS + GFX_USE_OS_CMSIS2 + GFX_USE_OS_KEIL + GFX_USE_OS_RTX5 + GFX_USE_OS_NIOS + GFX_USE_OS_QT != 1 * TRUE #error "GOS: More than one operation system has been defined as TRUE." #endif @@ -30,7 +30,7 @@ #if GFX_EMULATE_MALLOC #if GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX || GFX_USE_OS_ECOS || \ - (GFX_OS_HEAP_SIZE == 0 && (GFX_USE_OS_RAW32 || GFX_USE_OS_ARDUINO || GFX_USE_OS_CMSIS || GFX_USE_OS_KEIL)) + (GFX_OS_HEAP_SIZE == 0 && (GFX_USE_OS_RAW32 || GFX_USE_OS_ARDUINO || GFX_USE_OS_CMSIS || GFX_USE_OS_CMSIS2 || GFX_USE_OS_KEIL || GFX_USE_OS_RTX5)) #if GFX_DISPLAY_RULE_WARNINGS #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT #warning "GOS: Cannot emulate malloc as gfxAlloc() internally uses malloc on this platform" diff --git a/src/gos/gos_win32.c b/src/gos/gos_win32.c index ba4bbec2..1aa13dd6 100644 --- a/src/gos/gos_win32.c +++ b/src/gos/gos_win32.c @@ -86,6 +86,7 @@ typedef LONG (__stdcall *_NtQuerySemaphore)( PULONG ReturnLength OPTIONAL ); +/* - Left here simply because of its undocumented cleverness... semcount_t gfxSemCounter(gfxSem *pSem) { static _NtQuerySemaphore NtQuerySemaphore; struct _SEMAPHORE_BASIC_INFORMATION { @@ -100,6 +101,7 @@ semcount_t gfxSemCounter(gfxSem *pSem) { return BasicInfo.CurrentCount; } +*/ gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION(*fn,p), void *param) { (void) stackarea; diff --git a/src/gos/gos_win32.h b/src/gos/gos_win32.h index e6e45d2f..62602ad3 100644 --- a/src/gos/gos_win32.h +++ b/src/gos/gos_win32.h @@ -78,7 +78,6 @@ typedef HANDLE gfxThreadHandle; #define gfxSemWaitI(psem) gfxSemWait((psem), TIME_IMMEDIATE) #define gfxSemSignal(psem) ReleaseSemaphore(*(psem), 1, 0) #define gfxSemSignalI(psem) ReleaseSemaphore(*(psem), 1, 0) -#define gfxSemCounterI(psem) gfxSemCounter(psem) #define gfxThreadMe() GetCurrentThread() #define gfxThreadClose(thread) CloseHandle(thread) @@ -93,7 +92,6 @@ extern "C" { void gfxHalt(const char *msg); void gfxSleepMicroseconds(delaytime_t ms); bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); -semcount_t gfxSemCounter(gfxSem *pSem); void gfxSystemLock(void); void gfxSystemUnlock(void); gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION(*fn,p), void *param); diff --git a/src/gos/gos_x_threads.h b/src/gos/gos_x_threads.h index 05a08cc2..546e9e13 100644 --- a/src/gos/gos_x_threads.h +++ b/src/gos/gos_x_threads.h @@ -80,10 +80,6 @@ extern "C" { void gfxSemSignal(gfxSem *psem); void gfxSemSignalI(gfxSem *psem); - // Deprecated Semaphore functions (they still work here) - #define gfxSemCounter(psem) ((psem)->cnt) - #define gfxSemCounterI(psem) ((psem)->cnt) - // Threads gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); #define gfxThreadClose(thread) diff --git a/src/gwin/gwin_textedit.c b/src/gwin/gwin_textedit.c index ec67365e..8e639300 100644 --- a/src/gwin/gwin_textedit.c +++ b/src/gwin/gwin_textedit.c @@ -26,22 +26,58 @@ #define gh2obj ((GTexteditObject *)gh) #define gw2obj ((GTexteditObject *)gw) -static bool_t resizeText(GWidgetObject* gw, size_t pos, int32_t diff) { - char *p, *q; - size_t sz; - - p = (char *)gw->text; - sz = strlen(p)+1; - if (diff < 0) - memcpy(p+pos, p+pos-diff, sz-pos+diff); - if (!(p = gfxRealloc(p, sz, sz+diff))) - return FALSE; +static void TextEditRemoveChar(GWidgetObject* gw) { + char *p; + const char *q; + unsigned sz; + unsigned pos; + + sz = strlen(gw->text); + pos = gw2obj->cursorPos; + q = gw->text+pos; + + if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) { + // Allocate and then copy + if (!(p = gfxAlloc(sz))) + return; + if (pos) + memcpy(p, gw->text, pos); + memcpy(p+pos, q+1, sz-pos); + gw->g.flags |= GWIN_FLG_ALLOCTXT; + } else { + // Copy and then reallocate + memcpy((char *)q, q+1, sz-pos); + if (!(p = gfxRealloc((char *)gw->text, sz+1, sz))) // This should never fail as we are making it smaller + return; + } gw->text = p; - if (diff > 0) { - q = p + sz; - p += pos; - while(--q >= p) - q[diff] = q[0]; +} + +static bool_t TextEditAddChars(GWidgetObject* gw, unsigned cnt) { + char *p; + const char *q; + unsigned sz; + unsigned pos; + + // Get the size of the text buffer + sz = strlen(gw->text)+1; + pos = gw2obj->cursorPos; + + if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) { + if (!(p = gfxAlloc(sz+cnt))) + return FALSE; + memcpy(p, gw->text, pos); + memcpy(p+pos+cnt, gw->text+pos, sz-pos); + gw->g.flags |= GWIN_FLG_ALLOCTXT; + gw->text = p; + } else { + if (!(p = gfxRealloc((char *)gw->text, sz, sz+cnt))) + return FALSE; + gw->text = p; + q = p+pos; + p += sz; + while(--p >= q) + p[cnt] = p[0]; } return TRUE; } @@ -117,7 +153,7 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) { if (!gw2obj->cursorPos) return; gw2obj->cursorPos--; - resizeText(gw, gw2obj->cursorPos, -1); + TextEditRemoveChar(gw); break; case GKEY_TAB: case GKEY_LF: @@ -129,7 +165,7 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) { // Delete if (!gw->text[gw2obj->cursorPos]) return; - resizeText(gw, gw2obj->cursorPos, -1); + TextEditRemoveChar(gw); break; default: // Ignore any other control characters @@ -137,15 +173,15 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) { return; // Keep the edit length to less than the maximum - if (gw2obj->maxSize && gw2obj->cursorPos+pke->bytecount > gw2obj->maxSize) + if (gw2obj->maxSize && strlen(gw->text)+pke->bytecount > gw2obj->maxSize) return; // Make space - resizeText(gw, gw2obj->cursorPos, pke->bytecount); - - // Insert the character - memcpy((char *)gw->text+gw2obj->cursorPos, pke->c, pke->bytecount); - gw2obj->cursorPos += pke->bytecount; + if (TextEditAddChars(gw, pke->bytecount)) { + // Insert the characters + memcpy((char *)gw->text+gw2obj->cursorPos, pke->c, pke->bytecount); + gw2obj->cursorPos += pke->bytecount; + } break; } } @@ -196,24 +232,13 @@ static const gwidgetVMT texteditVMT = { GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit, size_t maxSize) { - char *p; - // Create the underlying widget if (!(wt = (GTexteditObject*)_gwidgetCreate(g, &wt->w, pInit, &texteditVMT))) return 0; wt->maxSize = maxSize; - // Reallocate the text (if necessary) - if (!(wt->w.g.flags & GWIN_FLG_ALLOCTXT)) { - if (!(p = gfxAlloc(wt->maxSize+1))) - return 0; - strncpy(p, wt->w.text, wt->maxSize); - wt->w.text = p; - wt->w.g.flags |= GWIN_FLG_ALLOCTXT; - } - - // Set text and cursor position + // Set cursor position wt->cursorPos = strlen(wt->w.text); gwinSetVisible(&wt->w.g, pInit->g.show); |