diff options
Diffstat (limited to 'drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c')
-rw-r--r-- | drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c | 268 |
1 files changed, 131 insertions, 137 deletions
diff --git a/drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c b/drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c index 917adadb84..7188244022 100644 --- a/drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c +++ b/drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c @@ -19,15 +19,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #if GFX_USE_GDISP -#define GDISP_DRIVER_VMT GDISPVMT_IS31FL3731C_QMK -#define GDISP_SCREEN_HEIGHT LED_HEIGHT -#define GDISP_SCREEN_WIDTH LED_WIDTH +# define GDISP_DRIVER_VMT GDISPVMT_IS31FL3731C_QMK +# define GDISP_SCREEN_HEIGHT LED_HEIGHT +# define GDISP_SCREEN_WIDTH LED_WIDTH -#include "gdisp_lld_config.h" -#include "src/gdisp/gdisp_driver.h" - -#include "board_is31fl3731c.h" +# include "gdisp_lld_config.h" +# include "src/gdisp/gdisp_driver.h" +# include "board_is31fl3731c.h" // Can't include led_tables from here extern const uint8_t CIE1931_CURVE[]; @@ -36,96 +35,96 @@ extern const uint8_t CIE1931_CURVE[]; /* Driver local definitions. */ /*===========================================================================*/ -#ifndef GDISP_INITIAL_CONTRAST - #define GDISP_INITIAL_CONTRAST 0 -#endif -#ifndef GDISP_INITIAL_BACKLIGHT - #define GDISP_INITIAL_BACKLIGHT 0 -#endif +# ifndef GDISP_INITIAL_CONTRAST +# define GDISP_INITIAL_CONTRAST 0 +# endif +# ifndef GDISP_INITIAL_BACKLIGHT +# define GDISP_INITIAL_BACKLIGHT 0 +# endif -#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) +# define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) -#define IS31_ADDR_DEFAULT 0x74 +# define IS31_ADDR_DEFAULT 0x74 -#define IS31_REG_CONFIG 0x00 +# define IS31_REG_CONFIG 0x00 // bits in reg -#define IS31_REG_CONFIG_PICTUREMODE 0x00 -#define IS31_REG_CONFIG_AUTOPLAYMODE 0x08 -#define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18 +# define IS31_REG_CONFIG_PICTUREMODE 0x00 +# define IS31_REG_CONFIG_AUTOPLAYMODE 0x08 +# define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18 // D2:D0 bits are starting frame for autoplay mode -#define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode +# define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode -#define IS31_REG_AUTOPLAYCTRL1 0x02 +# define IS31_REG_AUTOPLAYCTRL1 0x02 // D6:D4 number of loops (000=infty) // D2:D0 number of frames to be used -#define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms) +# define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms) -#define IS31_REG_DISPLAYOPT 0x05 -#define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames -#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8 +# define IS31_REG_DISPLAYOPT 0x05 +# define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames +# define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8 // D2:D0 bits blink period time (*0.27s) -#define IS31_REG_AUDIOSYNC 0x06 -#define IS31_REG_AUDIOSYNC_ENABLE 0x1 +# define IS31_REG_AUDIOSYNC 0x06 +# define IS31_REG_AUDIOSYNC_ENABLE 0x1 -#define IS31_REG_FRAMESTATE 0x07 +# define IS31_REG_FRAMESTATE 0x07 -#define IS31_REG_BREATHCTRL1 0x08 +# define IS31_REG_BREATHCTRL1 0x08 // D6:D4 fade out time (26ms*2^i) // D2:D0 fade in time (26ms*2^i) -#define IS31_REG_BREATHCTRL2 0x09 -#define IS31_REG_BREATHCTRL2_ENABLE 0x10 +# define IS31_REG_BREATHCTRL2 0x09 +# define IS31_REG_BREATHCTRL2_ENABLE 0x10 // D2:D0 extinguish time (3.5ms*2^i) -#define IS31_REG_SHUTDOWN 0x0A -#define IS31_REG_SHUTDOWN_OFF 0x0 -#define IS31_REG_SHUTDOWN_ON 0x1 +# define IS31_REG_SHUTDOWN 0x0A +# define IS31_REG_SHUTDOWN_OFF 0x0 +# define IS31_REG_SHUTDOWN_ON 0x1 -#define IS31_REG_AGCCTRL 0x0B -#define IS31_REG_ADCRATE 0x0C +# define IS31_REG_AGCCTRL 0x0B +# define IS31_REG_ADCRATE 0x0C -#define IS31_COMMANDREGISTER 0xFD -#define IS31_FUNCTIONREG 0x0B // helpfully called 'page nine' -#define IS31_FUNCTIONREG_SIZE 0xD +# define IS31_COMMANDREGISTER 0xFD +# define IS31_FUNCTIONREG 0x0B // helpfully called 'page nine' +# define IS31_FUNCTIONREG_SIZE 0xD -#define IS31_FRAME_SIZE 0xB4 +# define IS31_FRAME_SIZE 0xB4 -#define IS31_PWM_REG 0x24 -#define IS31_PWM_SIZE 0x90 +# define IS31_PWM_REG 0x24 +# define IS31_PWM_SIZE 0x90 -#define IS31_LED_MASK_SIZE 0x12 +# define IS31_LED_MASK_SIZE 0x12 -#define IS31 +# define IS31 /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ -typedef struct{ +typedef struct { uint8_t write_buffer_offset; uint8_t write_buffer[IS31_FRAME_SIZE]; uint8_t frame_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH]; uint8_t page; -}__attribute__((__packed__)) PrivData; +} __attribute__((__packed__)) PrivData; // Some common routines and macros -#define PRIV(g) ((PrivData*)g->priv) +# define PRIV(g) ((PrivData *)g->priv) /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ -static GFXINLINE void write_page(GDisplay* g, uint8_t page) { +static GFXINLINE void write_page(GDisplay *g, uint8_t page) { uint8_t tx[2] __attribute__((aligned(2))); tx[0] = IS31_COMMANDREGISTER; tx[1] = page; write_data(g, tx, 2); } -static GFXINLINE void write_register(GDisplay* g, uint8_t page, uint8_t reg, uint8_t data) { +static GFXINLINE void write_register(GDisplay *g, uint8_t page, uint8_t reg, uint8_t data) { uint8_t tx[2] __attribute__((aligned(2))); tx[0] = reg; tx[1] = data; @@ -136,7 +135,7 @@ static GFXINLINE void write_register(GDisplay* g, uint8_t page, uint8_t reg, uin static GFXINLINE void write_ram(GDisplay *g, uint8_t page, uint16_t offset, uint16_t length) { PRIV(g)->write_buffer_offset = offset; write_page(g, page); - write_data(g, (uint8_t*)PRIV(g), length + 1); + write_data(g, (uint8_t *)PRIV(g), length + 1); } LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { @@ -160,10 +159,9 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); gfxSleepMilliseconds(10); - // zero all LED registers on all 8 pages, and enable the mask __builtin_memcpy(PRIV(g)->write_buffer, get_led_mask(g), IS31_LED_MASK_SIZE); - for(uint8_t i=0; i<8; i++) { + for (uint8_t i = 0; i < 8; i++) { write_ram(g, i, 0, IS31_FRAME_SIZE); gfxSleepMilliseconds(1); } @@ -176,133 +174,129 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { post_init_board(g); /* Initialise the GDISP structure */ - g->g.Width = GDISP_SCREEN_WIDTH; - g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Orientation = GDISP_ROTATE_0; - g->g.Powermode = powerOff; - g->g.Backlight = GDISP_INITIAL_BACKLIGHT; - g->g.Contrast = GDISP_INITIAL_CONTRAST; + g->g.Powermode = powerOff; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; return TRUE; } -#if GDISP_HARDWARE_FLUSH - LLDSPEC void gdisp_lld_flush(GDisplay *g) { - // Don't flush if we don't need it. - if (!(g->flags & GDISP_FLG_NEEDFLUSH)) - return; - - PRIV(g)->page++; - PRIV(g)->page %= 2; - // TODO: some smarter algorithm for this - // We should run only one physical page at a time - // This way we don't need to send so much data, and - // we could use slightly less memory - uint8_t* src = PRIV(g)->frame_buffer; - for (int y=0;y<GDISP_SCREEN_HEIGHT;y++) { - for (int x=0;x<GDISP_SCREEN_WIDTH;x++) { - uint8_t val = (uint16_t)*src * g->g.Backlight / 100; - PRIV(g)->write_buffer[get_led_address(g, x, y)]=CIE1931_CURVE[val]; - ++src; - } +# if GDISP_HARDWARE_FLUSH +LLDSPEC void gdisp_lld_flush(GDisplay *g) { + // Don't flush if we don't need it. + if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return; + + PRIV(g)->page++; + PRIV(g)->page %= 2; + // TODO: some smarter algorithm for this + // We should run only one physical page at a time + // This way we don't need to send so much data, and + // we could use slightly less memory + uint8_t *src = PRIV(g)->frame_buffer; + for (int y = 0; y < GDISP_SCREEN_HEIGHT; y++) { + for (int x = 0; x < GDISP_SCREEN_WIDTH; x++) { + uint8_t val = (uint16_t)*src * g->g.Backlight / 100; + PRIV(g)->write_buffer[get_led_address(g, x, y)] = CIE1931_CURVE[val]; + ++src; } - write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE); - gfxSleepMilliseconds(1); - write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page); - - g->flags &= ~GDISP_FLG_NEEDFLUSH; } -#endif + write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE); + gfxSleepMilliseconds(1); + write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page); -#if GDISP_HARDWARE_DRAWPIXEL - LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { - coord_t x, y; + g->flags &= ~GDISP_FLG_NEEDFLUSH; +} +# endif - switch(g->g.Orientation) { +# if GDISP_HARDWARE_DRAWPIXEL +LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + coord_t x, y; + + switch (g->g.Orientation) { default: case GDISP_ROTATE_0: x = g->p.x; y = g->p.y; break; case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; + x = GDISP_SCREEN_WIDTH - 1 - g->p.x; y = g->p.y; break; - } - PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color); - g->flags |= GDISP_FLG_NEEDFLUSH; } -#endif + PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color); + g->flags |= GDISP_FLG_NEEDFLUSH; +} +# endif -#if GDISP_HARDWARE_PIXELREAD - LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { - coord_t x, y; +# if GDISP_HARDWARE_PIXELREAD +LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { + coord_t x, y; - switch(g->g.Orientation) { + switch (g->g.Orientation) { default: case GDISP_ROTATE_0: x = g->p.x; y = g->p.y; break; case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; + x = GDISP_SCREEN_WIDTH - 1 - g->p.x; y = g->p.y; break; - } - return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]); } -#endif + return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]); +} +# endif -#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL - LLDSPEC void gdisp_lld_control(GDisplay *g) { - switch(g->p.x) { +# 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: - case powerSleep: - case powerDeepSleep: - write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); - break; - case powerOn: - write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); - break; - default: - return; + if (g->g.Powermode == (powermode_t)g->p.ptr) return; + switch ((powermode_t)g->p.ptr) { + case powerOff: + case powerSleep: + case powerDeepSleep: + write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); + break; + case powerOn: + write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); + 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) { - /* Rotation is handled by the drawing routines */ - case GDISP_ROTATE_0: - case GDISP_ROTATE_180: - g->g.Height = GDISP_SCREEN_HEIGHT; - g->g.Width = GDISP_SCREEN_WIDTH; - break; - case GDISP_ROTATE_90: - case GDISP_ROTATE_270: - g->g.Height = GDISP_SCREEN_WIDTH; - g->g.Width = GDISP_SCREEN_HEIGHT; - break; - default: - return; + if (g->g.Orientation == (orientation_t)g->p.ptr) return; + switch ((orientation_t)g->p.ptr) { + /* Rotation is handled by the drawing routines */ + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; + default: + return; } g->g.Orientation = (orientation_t)g->p.ptr; return; case GDISP_CONTROL_BACKLIGHT: - if (g->g.Backlight == (unsigned)g->p.ptr) - return; - unsigned val = (unsigned)g->p.ptr; + if (g->g.Backlight == (unsigned)g->p.ptr) return; + unsigned val = (unsigned)g->p.ptr; g->g.Backlight = val > 100 ? 100 : val; g->flags |= GDISP_FLG_NEEDFLUSH; return; - } } -#endif // GDISP_NEED_CONTROL +} +# endif // GDISP_NEED_CONTROL -#endif // GFX_USE_GDISP +#endif // GFX_USE_GDISP |