From a79022147c1dbd23cbc9ee6ec7fbd4d14fe20cb2 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Mon, 16 Mar 2020 22:08:40 -0700 Subject: [PATCH] SSD1326 correction + prepare new slimproto message for artwork --- components/display/SSD1306.c | 15 +++------- components/display/core/gds_draw.c | 5 ++-- components/display/core/gds_private.h | 2 +- components/squeezelite/display.c | 42 +++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/components/display/SSD1306.c b/components/display/SSD1306.c index e1280b8b..fec88996 100644 --- a/components/display/SSD1306.c +++ b/components/display/SSD1306.c @@ -74,7 +74,7 @@ static void Update( struct GDS_Device* Device ) { CurrentPage = p + 1; // actual write - Device->WriteData( Device, Private->Shadowbuffer + p*width + first, last - first + 1 ); + Device->WriteData( Device, Private->Shadowbuffer + p*width + first, last - first + 1); } } #else @@ -114,10 +114,6 @@ static bool Init( struct GDS_Device* Device ) { // charge pump regulator, do direct init Device->WriteCommand( Device, 0x8D ); Device->WriteCommand( Device, 0x14 ); - - // set Clocks - Device->WriteCommand( Device, 0xD5 ); - Device->WriteCommand( Device, ( 0x08 << 4 ) | 0x00 ); // COM pins HW config (alternative:EN if 64, DIS if 32, remap:DIS) - some display might need something different Device->WriteCommand( Device, 0xDA ); @@ -126,12 +122,6 @@ static bool Init( struct GDS_Device* Device ) { // MUX Ratio Device->WriteCommand( Device, 0xA8 ); Device->WriteCommand( Device, Device->Height - 1); - // Page & GDDRAM Start Column High/Low - /* - Device->WriteCommand( Device, 0x00 ); - Device->WriteCommand( Device, 0x10 ); - Device->WriteCommand( Device, 0xB0 ); - */ // Display Offset Device->WriteCommand( Device, 0xD3 ); Device->WriteCommand( Device, 0 ); @@ -143,6 +133,9 @@ static bool Init( struct GDS_Device* Device ) { Device->SetHFlip( Device, false ); // no Display Inversion Device->WriteCommand( Device, 0xA6 ); + // set Clocks + Device->WriteCommand( Device, 0xD5 ); + Device->WriteCommand( Device, ( 0x08 << 4 ) | 0x00 ); // set Adressing Mode Horizontal Device->WriteCommand( Device, 0x20 ); Device->WriteCommand( Device, 0 ); diff --git a/components/display/core/gds_draw.c b/components/display/core/gds_draw.c index c85d39e6..ca18dc94 100644 --- a/components/display/core/gds_draw.c +++ b/components/display/core/gds_draw.c @@ -212,6 +212,7 @@ void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int uint8_t *optr = Device->Framebuffer; int LineLen = Device->Width >> 1; Height >>= 3; + Color &= 0x0f; for (int i = Width * Height, r = 0, c = 0; --i >= 0;) { uint8_t Byte = BitReverseTable256[*Data++]; // we need to linearize code to let compiler better optimize @@ -223,7 +224,7 @@ void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int *optr = (*optr & 0x0f) | (((Byte & 0x01)*Color)<<4); optr += LineLen; Byte >>= 1; *optr = (*optr & 0x0f) | (((Byte & 0x01)*Color)<<4); optr += LineLen; Byte >>= 1; *optr = (*optr & 0x0f) | (((Byte & 0x01)*Color)<<4); optr += LineLen; Byte >>= 1; - *optr = (*optr & 0x0f) | (((Byte & 0x01)*Color)<<4); optr += LineLen; Byte >>= 1; + *optr = (*optr & 0x0f) | (((Byte & 0x01)*Color)<<4); optr += LineLen; } else { *optr = (*optr & 0xf0) | (((Byte & 0x01)*Color)); optr += LineLen; Byte >>= 1; *optr = (*optr & 0xf0) | (((Byte & 0x01)*Color)); optr += LineLen; Byte >>= 1; @@ -232,7 +233,7 @@ void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int *optr = (*optr & 0xf0) | (((Byte & 0x01)*Color)); optr += LineLen; Byte >>= 1; *optr = (*optr & 0xf0) | (((Byte & 0x01)*Color)); optr += LineLen; Byte >>= 1; *optr = (*optr & 0xf0) | (((Byte & 0x01)*Color)); optr += LineLen; Byte >>= 1; - *optr = (*optr & 0xf0) | (((Byte & 0x01)*Color)); optr += LineLen; Byte >>= 1; + *optr = (*optr & 0xf0) | (((Byte & 0x01)*Color)); optr += LineLen; } // end of a column, move to next one if (++r == Height) { c++; r = 0; optr = Device->Framebuffer + (c >> 1); } diff --git a/components/display/core/gds_private.h b/components/display/core/gds_private.h index 6d3f46f1..816ddaf0 100644 --- a/components/display/core/gds_private.h +++ b/components/display/core/gds_private.h @@ -167,7 +167,7 @@ inline void IRAM_ATTR GDS_DrawPixel4Fast( struct GDS_Device* Device, int X, int uint8_t* FBOffset; FBOffset = Device->Framebuffer + ( (Y * Device->Width >> 1) + (X >> 1)); - *FBOffset = X & 0x01 ? (*FBOffset & 0x0f) | ((Color & 0x0f) << 4) : ((*FBOffset & 0xf0) | (Color & 0x0f)); + *FBOffset = X & 0x01 ? (*FBOffset & 0x0f) | ((Color & 0x0f) << 4) : ((*FBOffset & 0xf0) | (Color & 0x0f)); } inline void IRAM_ATTR GDS_DrawPixelFast( struct GDS_Device* Device, int X, int Y, int Color ) { diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c index e7061477..555ee983 100644 --- a/components/squeezelite/display.c +++ b/components/squeezelite/display.c @@ -26,6 +26,7 @@ #include "gds.h" #include "gds_text.h" #include "gds_draw.h" +#include "gds_image.h" #pragma pack(push, 1) @@ -59,6 +60,12 @@ struct grfg_packet { u16_t width; // # of pixels of scrollable }; +struct grfa_packet { + char opcode[4]; + u32_t length; + u32_t offset; +}; + struct visu_packet { char opcode[4]; u8_t which; @@ -130,6 +137,11 @@ static struct scroller_s { u32_t width; } scroller; +static struct { + u8_t *data; + u32_t size; +} artwork; + #define MAX_BARS 32 static EXT_RAM_ATTR struct { int bar_gap, bar_width, bar_border; @@ -174,6 +186,7 @@ static void grfe_handler( u8_t *data, int len); static void grfb_handler(u8_t *data, int len); static void grfs_handler(u8_t *data, int len); static void grfg_handler(u8_t *data, int len); +static void grfa_handler(u8_t *data, int len); static void visu_handler(u8_t *data, int len); static void displayer_task(void* arg); @@ -360,6 +373,8 @@ static bool handler(u8_t *data, int len){ grfs_handler(data, len); } else if (!strncmp((char*) data, "grfg", 4)) { grfg_handler(data, len); + } else if (!strncmp((char*) data, "grfa", 4)) { + grfa_handler(data, len); } else if (!strncmp((char*) data, "visu", 4)) { visu_handler(data, len); } else { @@ -636,6 +651,33 @@ static void grfg_handler(u8_t *data, int len) { vTaskResume(displayer.task); } + +/**************************************************************************************** + * Artwork + */ +static void grfa_handler(u8_t *data, int len) { + struct grfa_packet *pkt = (struct grfa_packet*) data; + int size = len - sizeof(struct grfa_packet); + int offset = htonl(pkt->offset); + int length = htonl(pkt->length); + + LOG_INFO("gfra l:%u o:%u s:%u", length, offset, size); + + // new grfa artwork, allocate memory + if (!offset) { + if (artwork.data) free(artwork.data); + artwork.data = malloc(length); + artwork.size = 0; + } + + // copy artwork data + memcpy(artwork.data + offset, data + sizeof(struct grfa_packet), size); + artwork.size += size; + if (artwork.size == length) { + GDS_DrawJPEG(display, artwork.data, 0, 32, GDS_IMAGE_CENTER); + } +} + /**************************************************************************************** * Update visualization bars */