Browse Source

display refactor

philippe44 5 years ago
parent
commit
a3d0b67670
43 changed files with 1562 additions and 1687 deletions
  1. 145 0
      components/display/SH1106.c
  2. 146 0
      components/display/SSD1306.c
  3. 2 2
      components/display/component.mk
  4. 92 0
      components/display/core/gds.c
  5. 30 0
      components/display/core/gds.h
  6. 20 0
      components/display/core/gds_default_if.h
  7. 321 0
      components/display/core/gds_draw.c
  8. 26 0
      components/display/core/gds_draw.h
  9. 6 6
      components/display/core/gds_err.h
  10. 38 71
      components/display/core/gds_font.c
  11. 91 0
      components/display/core/gds_font.h
  12. 130 0
      components/display/core/gds_private.h
  13. 195 0
      components/display/core/gds_text.c
  14. 45 0
      components/display/core/gds_text.h
  15. 32 46
      components/display/core/ifaces/default_if_i2c.c
  16. 109 0
      components/display/core/ifaces/default_if_spi.c
  17. 72 31
      components/display/display.c
  18. 3 34
      components/display/display.h
  19. 0 446
      components/display/driver_SSD13x6.c
  20. 0 0
      components/display/fonts/LICENSE-apache
  21. 0 0
      components/display/fonts/LICENSE-liberation-mono
  22. 2 2
      components/display/fonts/font_droid_sans_fallback_11x13.c
  23. 2 2
      components/display/fonts/font_droid_sans_fallback_15x17.c
  24. 2 2
      components/display/fonts/font_droid_sans_fallback_24x28.c
  25. 2 2
      components/display/fonts/font_droid_sans_mono_13x24.c
  26. 2 2
      components/display/fonts/font_droid_sans_mono_16x31.c
  27. 2 2
      components/display/fonts/font_droid_sans_mono_7x13.c
  28. 2 2
      components/display/fonts/font_liberation_mono_13x21.c
  29. 2 2
      components/display/fonts/font_liberation_mono_17x30.c
  30. 2 2
      components/display/fonts/font_liberation_mono_9x15.c
  31. 2 2
      components/display/fonts/font_line_1.c
  32. 2 2
      components/display/fonts/font_line_2.c
  33. 2 2
      components/display/fonts/font_tarable7seg_16x32.c
  34. 2 2
      components/display/fonts/font_tarable7seg_32x64.c
  35. 0 123
      components/display/tarablessd13x6/ifaces/default_if_spi.c
  36. 0 351
      components/display/tarablessd13x6/ssd13x6.c
  37. 0 99
      components/display/tarablessd13x6/ssd13x6.h
  38. 0 18
      components/display/tarablessd13x6/ssd13x6_default_if.h
  39. 0 253
      components/display/tarablessd13x6/ssd13x6_draw.c
  40. 0 54
      components/display/tarablessd13x6/ssd13x6_draw.h
  41. 0 91
      components/display/tarablessd13x6/ssd13x6_font.h
  42. 1 5
      components/raop/raop.c
  43. 32 31
      components/squeezelite/display.c

+ 145 - 0
components/display/SH1106.c

@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2017-2018 Tara Keeling
+ *				 2020 Philippe G. 
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <esp_heap_caps.h>
+#include <esp_log.h>
+
+#include "gds.h"
+#include "gds_private.h"
+
+#define SHADOW_BUFFER
+
+static char TAG[] = "SH1106";
+
+// Functions are not declared to minimize # of lines
+
+static void SetColumnAddress( struct GDS_Device* Device, uint8_t Start, uint8_t End ) {
+	// well, unfortunately this driver is 132 colums but most displays are 128...
+	if (Device->Width != 132) Start += 2;
+	Device->WriteCommand( Device, 0x10 | (Start >> 4) );
+	Device->WriteCommand( Device, 0x00 | (Start & 0x0f) );
+}
+
+static void SetPageAddress( struct GDS_Device* Device, uint8_t Start, uint8_t End ) {
+	Device->WriteCommand( Device, 0xB0 | Start );	
+}	
+
+static void Update( struct GDS_Device* Device ) {
+#ifdef SHADOW_BUFFER
+	// not sure the compiler does not have to redo all calculation in for loops, so local it is
+	int width = Device->Width, rows = Device->Height / 8;
+	uint8_t *optr = Device->Shadowbuffer, *iptr = Device->Framebuffer;
+	
+	// by row, find first and last columns that have been updated
+	for (int r = 0; r < rows; r++) {
+		uint8_t first = 0, last;	
+		for (int c = 0; c < width; c++) {
+			if (*iptr != *optr) {
+				if (!first) first = c + 1;
+				last = c ;
+			}	
+			*optr++ = *iptr++;
+		}
+		
+		// now update the display by "byte rows"
+		if (first--) {
+			SetColumnAddress( Device, first, last );
+			SetPageAddress( Device, r, r);
+			Device->WriteData( Device, Device->Shadowbuffer + r*width + first, last - first + 1);
+		}
+	}	
+#else	
+	// SH1106 requires a page-by-page update and has no end Page/Column
+	for (int i = 0; i < Device->Height / 8 ; i++) {
+		SH1106_SetPageAddress( Device, i, 0);
+		SH1106_SetColumnAddress( Device, 0, 0);			
+		SH1106_WriteData( Device, Device->Framebuffer + i*Device->Width, Device->Width );
+	}	
+#endif	
+}
+
+static void SetHFlip( struct GDS_Device* Device, bool On ) { Device->WriteCommand( Device, On ? 0xA1 : 0xA0 ); }
+static void SetVFlip( struct GDS_Device *Device, bool On ) { Device->WriteCommand( Device, On ? 0xC8 : 0xC0 ); }
+static void DisplayOn( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAF ); }
+static void DisplayOff( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAE ); }
+
+static void SetContrast( struct GDS_Device* Device, uint8_t Contrast ) {
+    Device->WriteCommand( Device, 0x81 );
+    Device->WriteCommand( Device, Contrast );
+}
+
+static bool Init( struct GDS_Device* Device ) {
+	Device->FramebufferSize = ( Device->Width * Device->Height ) / 8;	
+	Device->Framebuffer = calloc( 1, Device->FramebufferSize );
+    NullCheck( Device->Framebuffer, return false );
+	
+#ifdef SHADOW_BUFFER	
+	if (Device->IF == IF_I2C) Device->Shadowbuffer = malloc( Device->FramebufferSize );
+	else Device->Shadowbuffer = heap_caps_malloc( Device->FramebufferSize, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA );
+	NullCheck( Device->Shadowbuffer, return false );
+	memset(Device->Shadowbuffer, 0xFF, Device->FramebufferSize);
+#endif	
+		
+	// need to be off and disable display RAM
+	Device->DisplayOff( Device );
+    Device->WriteCommand( Device, 0xA5 );
+	
+	// charge pump regulator, do direct init
+	Device->WriteCommand( Device, 0xAD );
+	Device->WriteCommand( Device, 0x8B ); 
+			
+	// COM pins HW config (alternative:EN) - some display might need something difference
+	Device->WriteCommand( Device, 0xDA );
+	Device->WriteCommand( Device, 1 << 4);
+		
+	// MUX Ratio
+    Device->WriteCommand( Device, 0xA8 );
+    Device->WriteCommand( Device, Device->Height - 1);
+	// Display Offset
+    Device->WriteCommand( Device, 0xD3 );
+    Device->WriteCommand( Device, 0 );
+	// Display Start Line
+    Device->WriteCommand( Device, 0x40 + 0x00 );
+	Device->SetContrast( Device, 0x7F );
+	// set flip modes
+	Device->SetVFlip( Device, false );
+	Device->SetHFlip( Device, false );
+	// no Display Inversion
+    Device->WriteCommand( Device, 0xA6 );
+	// set Clocks
+    Device->WriteCommand( Device, 0xD5 );
+    Device->WriteCommand( Device, ( 0x08 << 4 ) | 0x00 );
+		
+	// gone with the wind
+	Device->WriteCommand( Device, 0xA4 );
+	Device->DisplayOn( Device );
+	Device->Update( Device );
+	
+	return true;
+}	
+
+static const struct GDS_Device SH1106 = {
+	.DisplayOn = DisplayOn, .DisplayOff = DisplayOff, .SetContrast = SetContrast,
+	.SetVFlip = SetVFlip, .SetHFlip = SetHFlip,
+	.DrawPixel = GDS_DrawPixel, .DrawPixelFast = GDS_DrawPixelFast,
+	.Update = Update, .Init = Init,
+};	
+
+struct GDS_Device* SH1106_Detect(char *Driver, struct GDS_Device* Device) {
+	if (!strcasestr(Driver, "SH1106")) return NULL;
+	
+	if (!Device) Device = calloc(1, sizeof(struct GDS_Device));
+	*Device = SH1106;	
+	ESP_LOGI(TAG, "SH1106 driver");
+	
+	return Device;
+}

+ 146 - 0
components/display/SSD1306.c

@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2017-2018 Tara Keeling
+ *				 2020 Philippe G.
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <esp_heap_caps.h>
+#include <esp_log.h>
+
+#include "gds.h"
+#include "gds_private.h"
+
+#define SHADOW_BUFFER
+
+static char TAG[] = "SSD1306";
+
+// Functions are not deckared to minimize # of lines
+
+static void SetColumnAddress( struct GDS_Device* Device, uint8_t Start, uint8_t End ) {
+	Device->WriteCommand( Device, 0x21 );
+	Device->WriteCommand( Device, Start );
+	Device->WriteCommand( Device, End );
+}
+static void SetPageAddress( struct GDS_Device* Device, uint8_t Start, uint8_t End ) {
+	Device->WriteCommand( Device, 0x22 );	
+	Device->WriteCommand( Device, Start );
+	Device->WriteCommand( Device, End );
+}
+
+static void Update( struct GDS_Device* Device ) {
+#ifdef SHADOW_BUFFER
+	// not sure the compiler does not have to redo all calculation in for loops, so local it is
+	int width = Device->Width, rows = Device->Height / 8;
+	uint8_t *optr = Device->Shadowbuffer, *iptr = Device->Framebuffer;
+	
+	// by row, find first and last columns that have been updated
+	for (int r = 0; r < rows; r++) {
+		uint8_t first = 0, last;	
+		for (int c = 0; c < width; c++) {
+			if (*iptr != *optr) {
+				if (!first) first = c + 1;
+				last = c ;
+			}	
+			*optr++ = *iptr++;
+		}
+		
+		// now update the display by "byte rows"
+		if (first--) {
+			SetColumnAddress( Device, first, last );
+			SetPageAddress( Device, r, r);
+			Device->WriteData( Device, Device->Shadowbuffer + r*width + first, last - first + 1);
+		}
+	}	
+#else	
+	// automatic counter and end Page/Column
+	SetColumnAddress( Device, 0, Device->Width - 1);
+	SetPageAddress( Device, 0, Device->Height / 8 - 1);
+	Device->WriteData( Device, Device->Framebuffer, Device->FramebufferSize );
+#endif	
+}
+
+static void SetHFlip( struct GDS_Device* Device, bool On ) { Device->WriteCommand( Device, On ? 0xA1 : 0xA0 ); }
+static void SetVFlip( struct GDS_Device *Device, bool On ) { Device->WriteCommand( Device, On ? 0xC8 : 0xC0 ); }
+static void DisplayOn( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAF ); }
+static void DisplayOff( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAE ); }
+
+static void SetContrast( struct GDS_Device* Device, uint8_t Contrast ) {
+    Device->WriteCommand( Device, 0x81 );
+    Device->WriteCommand( Device, Contrast );
+}
+
+static bool Init( struct GDS_Device* Device ) {
+	Device->FramebufferSize = ( Device->Width * Device->Height ) / 8;	
+	Device->Framebuffer = calloc( 1, Device->FramebufferSize );
+    NullCheck( Device->Framebuffer, return false );
+	
+#ifdef SHADOW_BUFFER	
+	if (Device->IF == IF_I2C) Device->Shadowbuffer = malloc( Device->FramebufferSize );
+	else Device->Shadowbuffer = heap_caps_malloc( Device->FramebufferSize, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA );
+	NullCheck( Device->Shadowbuffer, return false );
+	memset(Device->Shadowbuffer, 0xFF, Device->FramebufferSize);
+#endif	
+		
+	// need to be off and disable display RAM
+	Device->DisplayOff( Device );
+    Device->WriteCommand( Device, 0xA5 );
+	
+	// charge pump regulator, do direct init
+	Device->WriteCommand( Device, 0x8D );
+	Device->WriteCommand( Device, 0x14 ); 
+			
+	// COM pins HW config (alternative:EN if 64, DIS if 32, remap:DIS) - some display might need something difference
+	Device->WriteCommand( Device, 0xDA );
+	Device->WriteCommand( Device, ((Device->Height == 64 ? 1 : 0) << 4) | (0 < 5) );
+		
+	// MUX Ratio
+    Device->WriteCommand( Device, 0xA8 );
+    Device->WriteCommand( Device, Device->Height - 1);
+	// Display Offset
+    Device->WriteCommand( Device, 0xD3 );
+    Device->WriteCommand( Device, 0 );
+	// Display Start Line
+    Device->WriteCommand( Device, 0x40 + 0x00 );
+	Device->SetContrast( Device, 0x7F );
+	// set flip modes
+	Device->SetVFlip( Device, false );
+	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 );
+	
+	// gone with the wind
+	Device->WriteCommand( Device, 0xA4 );
+	Device->DisplayOn( Device );
+	Device->Update( Device );
+	
+	return true;
+}	
+
+static const struct GDS_Device SSD1306 = {
+	.DisplayOn = DisplayOn, .DisplayOff = DisplayOff, .SetContrast = SetContrast,
+	.SetVFlip = SetVFlip, .SetHFlip = SetHFlip,
+	.DrawPixel = GDS_DrawPixel, .DrawPixelFast = GDS_DrawPixelFast,
+	.Update = Update, .Init = Init,
+};	
+
+struct GDS_Device* SSD1306_Detect(char *Driver, struct GDS_Device* Device) {
+	if (!strcasestr(Driver, "SSD1306")) return NULL;
+	
+	if (!Device) Device = calloc(1, sizeof(struct GDS_Device));
+	*Device = SSD1306;	
+	ESP_LOGI(TAG, "SSD1306 driver");
+	
+	return Device;
+}

+ 2 - 2
components/display/component.mk

@@ -7,6 +7,6 @@
 # please read the SDK documents if you need to do this.
 # please read the SDK documents if you need to do this.
 #
 #
 
 
-COMPONENT_SRCDIRS := . tarablessd13x6 tarablessd13x6/fonts tarablessd13x6/ifaces
+COMPONENT_SRCDIRS := . core core/ifaces fonts 
 COMPONENT_ADD_INCLUDEDIRS := .
 COMPONENT_ADD_INCLUDEDIRS := .
-COMPONENT_ADD_INCLUDEDIRS += ./tarablessd13x6 
+COMPONENT_ADD_INCLUDEDIRS += ./core

+ 92 - 0
components/display/core/gds.c

@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2017-2018 Tara Keeling
+ *				 2020 Philippe G. 
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <stdint.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "esp_log.h"
+
+#include "gds.h"
+#include "gds_private.h"
+
+static struct GDS_Device Display;
+
+static char TAG[] = "gds";
+
+struct GDS_Device*	GDS_AutoDetect( char *Driver, GDS_DetectFunc DetectFunc[] ) {
+	for (int i = 0; DetectFunc[i]; i++) {
+		if (DetectFunc[i](Driver, &Display)) {
+			ESP_LOGD(TAG, "Detected driver %p", &Display);
+			return &Display;
+		}	
+	}
+	
+	return NULL;
+}
+
+void GDS_ClearExt(struct GDS_Device* Device, bool full, ...) {
+	bool commit = true;
+	
+	if (full) {
+		GDS_Clear( Device, GDS_COLOR_BLACK ); 
+	} else {
+		va_list args;
+		va_start(args, full);
+		commit = va_arg(args, int);
+		int x1 = va_arg(args, int), y1 = va_arg(args, int), x2 = va_arg(args, int), y2 = va_arg(args, int);
+		if (x2 < 0) x2 = Device->Width - 1;
+		if (y2 < 0) y2 = Device->Height - 1;
+		GDS_ClearWindow( Device, x1, y1, x2, y2, GDS_COLOR_BLACK );
+		va_end(args);
+	}
+	
+	Device->Dirty = true;
+	if (commit)	GDS_Update(Device);		
+}	
+
+void GDS_Clear( struct GDS_Device* Device, int Color ) {
+    memset( Device->Framebuffer, Color, Device->FramebufferSize );
+}
+
+void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color ) {
+	// cheap optimization on boundaries
+	if (x1 == 0 && x2 == Device->Width - 1 && y1 % 8 == 0 && (y2 + 1) % 8 == 0) {
+		memset( Device->Framebuffer + (y1 / 8) * Device->Width, 0, (y2 - y1 + 1) / 8 * Device->Width );
+	} else {
+		for (int y = y1; y <= y2; y++) {
+			for (int x = x1; x <= x2; x++) {
+				Device->DrawPixelFast( Device, x, y, Color);
+			}		
+		}	
+	}	
+}
+
+void GDS_Update( struct GDS_Device* Device ) {
+	if (Device->Dirty) Device->Update( Device );
+	Device->Dirty = false;
+}
+
+bool GDS_Reset( struct GDS_Device* Device ) {
+	if ( Device->RSTPin >= 0 ) {
+		gpio_set_level( Device->RSTPin, 0 );
+		vTaskDelay( pdMS_TO_TICKS( 100 ) );
+        gpio_set_level( Device->RSTPin, 1 );
+    }
+    return true;
+}
+
+void GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast ) { Device->SetContrast( Device, Contrast); }
+void GDS_SetHFlip( struct GDS_Device* Device, bool On ) { Device->SetHFlip( Device, On ); }
+void GDS_SetVFlip( struct GDS_Device* Device, bool On ) { Device->SetVFlip( Device, On ); }
+int	GDS_GetWidth( struct GDS_Device* Device ) { return Device->Width; }
+int	GDS_GetHeight( struct GDS_Device* Device ) { return Device->Height; }
+void GDS_DisplayOn( struct GDS_Device* Device ) { Device->DisplayOn( Device ); }
+void GDS_DisplayOff( struct GDS_Device* Device ) { Device->DisplayOff( Device ); }

+ 30 - 0
components/display/core/gds.h

@@ -0,0 +1,30 @@
+#ifndef _GDS_H_
+#define _GDS_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define GDS_COLOR_BLACK 0
+#define GDS_COLOR_WHITE 1
+#define GDS_COLOR_XOR 2
+
+struct GDS_Device;
+struct GDS_FontDef;
+
+typedef struct GDS_Device* (*GDS_DetectFunc)(char *Driver, struct GDS_Device *Device);
+
+struct GDS_Device*	GDS_AutoDetect( char *Driver, GDS_DetectFunc[] );
+
+void 	GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast );
+void 	GDS_DisplayOn( struct GDS_Device* Device );
+void 	GDS_DisplayOff( struct GDS_Device* Device ); 
+void 	GDS_Update( struct GDS_Device* Device );
+void 	GDS_SetHFlip( struct GDS_Device* Device, bool On );
+void 	GDS_SetVFlip( struct GDS_Device* Device, bool On );
+int 	GDS_GetWidth( struct GDS_Device* Device );
+int 	GDS_GetHeight( struct GDS_Device* Device );
+void 	GDS_ClearExt( struct GDS_Device* Device, bool full, ...);
+void 	GDS_Clear( struct GDS_Device* Device, int Color );
+void 	GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color );
+
+#endif

+ 20 - 0
components/display/core/gds_default_if.h

@@ -0,0 +1,20 @@
+#ifndef _GDS_DEFAULT_IF_H_
+#define _GDS_DEFAULT_IF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct GDS_Device;
+
+bool GDS_I2CInit( int PortNumber, int SDA, int SCL );
+bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int I2CAddress, int RSTPin );
+
+bool GDS_SPIInit( int SPI, int DC );
+bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int Speed );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 321 - 0
components/display/core/gds_draw.c

@@ -0,0 +1,321 @@
+/**
+ * Copyright (c) 2017-2018 Tara Keeling
+ *				 2020 Philippe G.
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <math.h>
+#include <esp_attr.h>
+
+#include "gds.h"
+#include "gds_private.h"
+#include "gds_draw.h"
+
+static const unsigned char BitReverseTable256[] = 
+{
+  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
+  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
+  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
+  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
+  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
+  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
+  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
+  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
+  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
+  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+__attribute__( ( always_inline ) ) static inline bool IsPixelVisible( struct GDS_Device* Device, int x, int y )  {
+    bool Result = (
+        ( x >= 0 ) &&
+        ( x < Device->Width ) &&
+        ( y >= 0 ) &&
+        ( y < Device->Height )
+    ) ? true : false;
+
+#if CONFIG_GDS_CLIPDEBUG > 0
+    if ( Result == false ) {
+        ClipDebug( x, y );
+    }
+#endif
+
+    return Result;
+}
+
+__attribute__( ( always_inline ) ) static inline void SwapInt( int* a, int* b ) {
+    int Temp = *b;
+
+    *b = *a;
+    *a = Temp;
+}
+
+inline void IRAM_ATTR GDS_DrawPixelFast( struct GDS_Device* Device, int X, int Y, int Color ) {
+    uint32_t YBit = ( Y & 0x07 );
+    uint8_t* FBOffset = NULL;
+
+    /* 
+     * We only need to modify the Y coordinate since the pitch
+     * of the screen is the same as the width.
+     * Dividing Y by 8 gives us which row the pixel is in but not
+     * the bit position.
+     */
+    Y>>= 3;
+
+    FBOffset = Device->Framebuffer + ( ( Y * Device->Width ) + X );
+
+    if ( Color == GDS_COLOR_XOR ) {
+        *FBOffset ^= BIT( YBit );
+    } else {
+        *FBOffset = ( Color == GDS_COLOR_WHITE ) ? *FBOffset | BIT( YBit ) : *FBOffset & ~BIT( YBit );
+    }
+}
+
+void IRAM_ATTR GDS_DrawPixel( struct GDS_Device* Device, int x, int y, int Color ) {
+    if ( IsPixelVisible( Device, x, y ) == true ) {
+        Device->DrawPixelFast( Device, x, y, Color );
+    }
+}
+
+inline void IRAM_ATTR GDS_DrawPixel4Fast( struct GDS_Device* Device, int X, int Y, int Color ) {
+    uint32_t YBit = ( Y & 0x07 );
+    uint8_t* FBOffset = NULL;
+
+    /* 
+     * We only need to modify the Y coordinate since the pitch
+     * of the screen is the same as the width.
+     * Dividing Y by 8 gives us which row the pixel is in but not
+     * the bit position.
+     */
+    Y>>= 3;
+
+    FBOffset = Device->Framebuffer + ( ( Y * Device->Width ) + X );
+
+    if ( Color == GDS_COLOR_XOR ) {
+        *FBOffset ^= BIT( YBit );
+    } else {
+        *FBOffset = ( Color == GDS_COLOR_WHITE ) ? *FBOffset | BIT( YBit ) : *FBOffset & ~BIT( YBit );
+    }
+}
+
+void IRAM_ATTR GDS_DrawPixel4( struct GDS_Device* Device, int x, int y, int Color ) {
+    if ( IsPixelVisible( Device, x, y ) == true ) {
+        Device->DrawPixelFast( Device, x, y, Color );
+    }
+}
+
+void IRAM_ATTR GDS_DrawHLine( struct GDS_Device* Device, int x, int y, int Width, int Color ) {
+    int XEnd = x + Width;
+
+	Device->Dirty = true;
+	
+	if (x < 0) x = 0;
+	if (XEnd >= Device->Width) XEnd = Device->Width - 1;
+	
+	if (y < 0) y = 0;
+	else if (y >= Device->Height) x = Device->Height - 1;
+
+    for ( ; x < XEnd; x++ ) {
+    //    if ( IsPixelVisible( Device, x, y ) == true ) {
+            Device->DrawPixelFast( Device, x, y, Color );
+      //  } else {
+       //     break;
+       // }
+    }
+}
+
+void IRAM_ATTR GDS_DrawVLine( struct GDS_Device* Device, int x, int y, int Height, int Color ) {
+    int YEnd = y + Height;
+
+	Device->Dirty = true;
+
+    for ( ; y < YEnd; y++ ) {
+        if ( IsPixelVisible( Device, x, y ) == true ) {
+            Device->DrawPixel( Device, x, y, Color );
+        } else {
+            break;
+        }
+    }
+}
+
+static inline void IRAM_ATTR DrawWideLine( struct GDS_Device* Device, int x0, int y0, int x1, int y1, int Color ) {
+    int dx = ( x1 - x0 );
+    int dy = ( y1 - y0 );
+    int Error = 0;
+    int Incr = 1;
+    int x = x0;
+    int y = y0;
+
+    if ( dy < 0 ) {
+        Incr = -1;
+        dy = -dy;
+    }
+
+    Error = ( dy * 2 ) - dx;
+
+    for ( ; x < x1; x++ ) {
+        if ( IsPixelVisible( Device, x, y ) == true ) {
+            Device->DrawPixelFast( Device, x, y, Color );
+        }
+
+        if ( Error > 0 ) {
+            Error-= ( dx * 2 );
+            y+= Incr;
+        }
+
+        Error+= ( dy * 2 );
+    }
+}
+
+static inline void IRAM_ATTR DrawTallLine( struct GDS_Device* Device, int x0, int y0, int x1, int y1, int Color ) {
+    int dx = ( x1 - x0 );
+    int dy = ( y1 - y0 );
+    int Error = 0;
+    int Incr = 1;
+    int x = x0;
+    int y = y0;
+
+    if ( dx < 0 ) {
+        Incr = -1;
+        dx = -dx;
+    }
+
+    Error = ( dx * 2 ) - dy;
+
+    for ( ; y < y1; y++ ) {
+        if ( IsPixelVisible( Device, x, y ) == true ) {
+            Device->DrawPixelFast( Device, x, y, Color );
+        }
+
+        if ( Error > 0 ) {
+            Error-= ( dy * 2 );
+            x+= Incr;
+        }
+
+        Error+= ( dx * 2 );
+    }
+}
+
+void IRAM_ATTR GDS_DrawLine( struct GDS_Device* Device, int x0, int y0, int x1, int y1, int Color ) {
+    if ( x0 == x1 ) {
+        GDS_DrawVLine( Device, x0, y0, ( y1 - y0 ), Color );
+    } else if ( y0 == y1 ) {
+        GDS_DrawHLine( Device, x0, y0, ( x1 - x0 ), Color );
+    } else {
+		Device->Dirty = true;
+        if ( abs( x1 - x0 ) > abs( y1 - y0 ) ) {
+            /* Wide ( run > rise ) */
+            if ( x0 > x1 ) {
+                SwapInt( &x0, &x1 );
+                SwapInt( &y0, &y1 );
+            }
+
+            DrawWideLine( Device, x0, y0, x1, y1, Color );
+        } else {
+            /* Tall ( rise > run ) */
+            if ( y0 > y1 ) {
+                SwapInt( &y0, &y1 );
+                SwapInt( &x0, &x1 );
+            }
+
+            DrawTallLine( Device, x0, y0, x1, y1, Color );
+        }
+    }
+}
+
+void IRAM_ATTR GDS_DrawBox( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color, bool Fill ) {
+    int Width = ( x2 - x1 );
+    int Height = ( y2 - y1 );
+
+	Device->Dirty = true;
+	
+    if ( Fill == false ) {
+        /* Top side */
+        GDS_DrawHLine( Device, x1, y1, Width, Color );
+
+        /* Bottom side */
+        GDS_DrawHLine( Device, x1, y1 + Height, Width, Color );
+
+        /* Left side */
+        GDS_DrawVLine( Device, x1, y1, Height, Color );
+
+        /* Right side */
+        GDS_DrawVLine( Device, x1 + Width, y1, Height, Color );
+    } else {
+        /* Fill the box by drawing horizontal lines */
+        for ( ; y1 <= y2; y1++ ) {
+            GDS_DrawHLine( Device, x1, y1, Width, Color );
+        }
+    }
+}
+
+
+/****************************************************************************************
+ * Process graphic display data from column-oriented data (MSbit first)
+ */
+void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int Height) {
+	if (!Height) Height = Device->Height;
+	if (!Width) Width = Device->Width;
+
+	// need to do row/col swap and bit-reverse
+	int Rows = Height / 8;
+	for (int r = 0; r < Rows; r++) {
+		uint8_t *optr = Device->Framebuffer + r*Device->Width, *iptr = Data + r;
+		for (int c = Width; --c >= 0;) {
+			*optr++ = BitReverseTable256[*iptr];;
+			iptr += Rows;
+		}	
+	}
+	
+	Device->Dirty = true;
+}
+
+/****************************************************************************************
+ * Process graphic display data MSBit first
+ * WARNING: this has not been tested yet
+ */
+ /*
+static void draw_raw(int x1, int y1, int x2, int y2, bool by_column, bool MSb, u8_t *data) {
+	// default end point to display size
+	if (x2 == -1) x2 = Display.Width - 1;
+	if (y2 == -1) y2 = Display.Height - 1;
+	
+	display->dirty = true;
+	
+	//	not a boundary draw
+	// same comment about bit depth
+	if (y1 % 8 || y2 % 8 || x1 % 8 | x2 % 8) {
+		ESP_LOGW(TAG, "can't write on non cols/rows boundaries for now");
+	} else {	
+		// set addressing mode to match data
+		if (by_column) {
+			// copy the window and do row/col exchange
+			for (int r = y1/8; r <=  y2/8; r++) {
+				uint8_t *optr = Display.Framebuffer + r*Display.Width + x1, *iptr = data + r;
+				for (int c = x1; c <= x2; c++) {
+					*optr++ = MSb ? BitReverseTable256[*iptr] : *iptr;
+					iptr += (y2-y1)/8 + 1;
+			}	
+			}	
+		} else {
+			// just copy the window inside the frame buffer
+			for (int r = y1/8; r <= y2/8; r++) {
+				uint8_t *optr = Display.Framebuffer + r*Display.Width + x1, *iptr = data + r*(x2-x1+1);
+				for (int c = x1; c <= x2; c++) *optr++ = *iptr++;
+			}	
+		}
+	}	
+}
+*/

+ 26 - 0
components/display/core/gds_draw.h

@@ -0,0 +1,26 @@
+#ifndef _GDS_DRAW_H_
+#define _GDS_DRAW_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "esp_attr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct GDS_Device;
+
+void IRAM_ATTR GDS_DrawHLine( struct GDS_Device* Device, int x, int y, int Width, int Color );
+void IRAM_ATTR GDS_DrawVLine( struct GDS_Device* Device, int x, int y, int Height, int Color );
+void IRAM_ATTR GDS_DrawLine( struct GDS_Device* Device, int x0, int y0, int x1, int y1, int Color );
+void IRAM_ATTR GDS_DrawBox( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color, bool Fill );
+
+// draw a bitmap with source 1-bit depth organized in column and col0 = bit7 of byte 0
+void IRAM_ATTR GDS_DrawBitmapCBR( struct GDS_Device* Device, uint8_t *Data, int Width, int Height);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 6 - 6
components/display/tarablessd13x6/ssd13x6_err.h → components/display/core/gds_err.h

@@ -1,15 +1,15 @@
-#ifndef _SSD13x6_ERR_H_
-#define _SSD13x6_ERR_H_
+#ifndef _GDS_ERR_H_
+#define _GDS_ERR_H_
 
 
 #include <esp_log.h>
 #include <esp_log.h>
 
 
-#define SSD13x6_DoAbort( )
+#define GDS_DoAbort( )
 
 
 #if ! defined NullCheck
 #if ! defined NullCheck
     #define NullCheck( ptr, retexpr ) { \
     #define NullCheck( ptr, retexpr ) { \
         if ( ptr == NULL ) { \
         if ( ptr == NULL ) { \
             ESP_LOGE( __FUNCTION__, "%s == NULL", #ptr ); \
             ESP_LOGE( __FUNCTION__, "%s == NULL", #ptr ); \
-            SSD13x6_DoAbort( ); \
+            GDS_DoAbort( ); \
             retexpr; \
             retexpr; \
         } \
         } \
     }
     }
@@ -20,7 +20,7 @@
         esp_err_t __err_rc = ( expr ); \
         esp_err_t __err_rc = ( expr ); \
         if ( __err_rc != ESP_OK ) { \
         if ( __err_rc != ESP_OK ) { \
             ESP_LOGE( __FUNCTION__, "%s != ESP_OK, result: %d", #expr, __err_rc ); \
             ESP_LOGE( __FUNCTION__, "%s != ESP_OK, result: %d", #expr, __err_rc ); \
-            SSD13x6_DoAbort( ); \
+            GDS_DoAbort( ); \
             retexpr; \
             retexpr; \
         } \
         } \
     }
     }
@@ -30,7 +30,7 @@
     #define CheckBounds( expr, retexpr ) { \
     #define CheckBounds( expr, retexpr ) { \
         if ( expr ) { \
         if ( expr ) { \
             ESP_LOGE( __FUNCTION__, "Line %d: %s", __LINE__, #expr ); \
             ESP_LOGE( __FUNCTION__, "Line %d: %s", __LINE__, #expr ); \
-            SSD13x6_DoAbort( ); \
+            GDS_DoAbort( ); \
             retexpr; \
             retexpr; \
         } \
         } \
     }
     }

+ 38 - 71
components/display/tarablessd13x6/ssd13x6_font.c → components/display/core/gds_font.c

@@ -9,11 +9,13 @@
 #include <string.h>
 #include <string.h>
 #include <stdint.h>
 #include <stdint.h>
 #include <math.h>
 #include <math.h>
-#include "ssd13x6.h"
-#include "ssd13x6_draw.h"
-#include "ssd13x6_font.h"
+#include "gds.h"
+#include "gds_draw.h"
+#include "gds_font.h"
+#include "gds_private.h"
+#include "gds_err.h"
 
 
-static int RoundUpFontHeight( const struct SSD13x6_FontDef* Font ) {
+static int RoundUpFontHeight( const struct GDS_FontDef* Font ) {
     int Height = Font->Height;
     int Height = Font->Height;
 
 
     if ( ( Height % 8 ) != 0 ) {
     if ( ( Height % 8 ) != 0 ) {
@@ -23,11 +25,11 @@ static int RoundUpFontHeight( const struct SSD13x6_FontDef* Font ) {
     return Height;
     return Height;
 }
 }
 
 
-static const uint8_t* GetCharPtr( const struct SSD13x6_FontDef* Font, char Character ) {
+static const uint8_t* GetCharPtr( const struct GDS_FontDef* Font, char Character ) {
     return &Font->FontData[ ( Character - Font->StartChar ) * ( ( Font->Width * ( RoundUpFontHeight( Font ) / 8 ) ) + 1 ) ];
     return &Font->FontData[ ( Character - Font->StartChar ) * ( ( Font->Width * ( RoundUpFontHeight( Font ) / 8 ) ) + 1 ) ];
 }
 }
 
 
-void SSD13x6_FontDrawChar( struct SSD13x6_Device* DisplayHandle, char Character, int x, int y, int Color ) {
+void GDS_FontDrawChar( struct GDS_Device* Device, char Character, int x, int y, int Color ) {
     const uint8_t* GlyphData = NULL;
     const uint8_t* GlyphData = NULL;
     int GlyphColumnLen = 0;
     int GlyphColumnLen = 0;
     int CharStartX =  0;
     int CharStartX =  0;
@@ -42,18 +44,15 @@ void SSD13x6_FontDrawChar( struct SSD13x6_Device* DisplayHandle, char Character,
     int YBit = 0;
     int YBit = 0;
     int i = 0;
     int i = 0;
 
 
-    NullCheck( DisplayHandle, return );
-    NullCheck( DisplayHandle->Font, return );
-    
-    NullCheck( ( GlyphData = GetCharPtr( DisplayHandle->Font, Character ) ), return );
+    NullCheck( ( GlyphData = GetCharPtr( Device->Font, Character ) ), return );
 
 
-    if ( Character >= DisplayHandle->Font->StartChar && Character <= DisplayHandle->Font->EndChar ) {
+    if ( Character >= Device->Font->StartChar && Character <= Device->Font->EndChar ) {
         /* The first byte in the glyph data is the width of the character in pixels, skip over */
         /* The first byte in the glyph data is the width of the character in pixels, skip over */
         GlyphData++;
         GlyphData++;
-        GlyphColumnLen = RoundUpFontHeight( DisplayHandle->Font ) / 8;
+        GlyphColumnLen = RoundUpFontHeight( Device->Font ) / 8;
         
         
-        CharWidth = SSD13x6_FontGetCharWidth( DisplayHandle, Character );
-        CharHeight = SSD13x6_FontGetHeight( DisplayHandle );
+        CharWidth = GDS_FontGetCharWidth( Device, Character );
+        CharHeight = GDS_FontGetHeight( Device );
 
 
         CharStartX = x;
         CharStartX = x;
         CharStartY = y;
         CharStartY = y;
@@ -74,14 +73,15 @@ void SSD13x6_FontDrawChar( struct SSD13x6_Device* DisplayHandle, char Character,
         CharStartY+= OffsetY;
         CharStartY+= OffsetY;
 
 
         /* Do not attempt to draw if this character is entirely offscreen */
         /* Do not attempt to draw if this character is entirely offscreen */
-        if ( CharEndX < 0 || CharStartX >= DisplayHandle->Width || CharEndY < 0 || CharStartY >= DisplayHandle->Height ) {
+        if ( CharEndX < 0 || CharStartX >= Device->Width || CharEndY < 0 || CharStartY >= Device->Height ) {
             ClipDebug( x, y );
             ClipDebug( x, y );
             return;
             return;
         }
         }
 
 
         /* Do not attempt to draw past the end of the screen */
         /* Do not attempt to draw past the end of the screen */
-        CharEndX = ( CharEndX >= DisplayHandle->Width ) ? DisplayHandle->Width - 1 : CharEndX;
-        CharEndY = ( CharEndY >= DisplayHandle->Height ) ? DisplayHandle->Height - 1 : CharEndY;
+        CharEndX = ( CharEndX >= Device->Width ) ? Device->Width - 1 : CharEndX;
+        CharEndY = ( CharEndY >= Device->Height ) ? Device->Height - 1 : CharEndY;
+		Device->Dirty = true;
 
 
         for ( x = CharStartX; x < CharEndX; x++ ) {
         for ( x = CharStartX; x < CharEndX; x++ ) {
             for ( y = CharStartY, i = 0; y < CharEndY && i < CharHeight; y++, i++ ) {
             for ( y = CharStartY, i = 0; y < CharEndY && i < CharHeight; y++, i++ ) {
@@ -89,7 +89,7 @@ void SSD13x6_FontDrawChar( struct SSD13x6_Device* DisplayHandle, char Character,
                 YBit = ( i + OffsetY ) & 0x07;
                 YBit = ( i + OffsetY ) & 0x07;
 
 
                 if ( GlyphData[ YByte ] & BIT( YBit ) ) {
                 if ( GlyphData[ YByte ] & BIT( YBit ) ) {
-                    SSD13x6_DrawPixel( DisplayHandle, x, y, Color );
+                    Device->DrawPixel( Device, x, y, Color );
                 }            
                 }            
             }
             }
 
 
@@ -98,10 +98,7 @@ void SSD13x6_FontDrawChar( struct SSD13x6_Device* DisplayHandle, char Character,
     }
     }
 }
 }
 
 
-bool SSD13x6_SetFont( struct SSD13x6_Device* Display, const struct SSD13x6_FontDef* Font ) {
-    NullCheck( Display, return false );
-    NullCheck( Font, return false );
-
+bool GDS_SetFont( struct GDS_Device* Display, const struct GDS_FontDef* Font ) {
     Display->FontForceProportional = false;
     Display->FontForceProportional = false;
     Display->FontForceMonospace = false;
     Display->FontForceMonospace = false;
     Display->Font = Font;
     Display->Font = Font;
@@ -109,41 +106,26 @@ bool SSD13x6_SetFont( struct SSD13x6_Device* Display, const struct SSD13x6_FontD
     return true;
     return true;
 }
 }
 
 
-void SSD13x6_FontForceProportional( struct SSD13x6_Device* Display, bool Force ) {
-    NullCheck( Display, return );
-    NullCheck( Display->Font, return );
-
+void GDS_FontForceProportional( struct GDS_Device* Display, bool Force ) {
     Display->FontForceProportional = Force;
     Display->FontForceProportional = Force;
 }
 }
 
 
-void SSD13x6_FontForceMonospace( struct SSD13x6_Device* Display, bool Force ) {
-    NullCheck( Display, return );
-    NullCheck( Display->Font, return );
-
+void GDS_FontForceMonospace( struct GDS_Device* Display, bool Force ) {
     Display->FontForceMonospace = Force;
     Display->FontForceMonospace = Force;
 }
 }
 
 
-int SSD13x6_FontGetWidth( struct SSD13x6_Device* Display ) {
-    NullCheck( Display, return 0 );
-    NullCheck( Display->Font, return 0 );
-
+int GDS_FontGetWidth( struct GDS_Device* Display ) {
     return Display->Font->Width;
     return Display->Font->Width;
 }
 }
 
 
-int SSD13x6_FontGetHeight( struct SSD13x6_Device* Display ) {
-    NullCheck( Display, return 0 );
-    NullCheck( Display->Font, return 0 );
-
+int GDS_FontGetHeight( struct GDS_Device* Display ) {
     return Display->Font->Height;
     return Display->Font->Height;
 }
 }
 
 
-int SSD13x6_FontGetCharWidth( struct SSD13x6_Device* Display, char Character ) {
+int GDS_FontGetCharWidth( struct GDS_Device* Display, char Character ) {
     const uint8_t* CharPtr = NULL;
     const uint8_t* CharPtr = NULL;
     int Width = 0;
     int Width = 0;
 
 
-    NullCheck( Display, return 0 );
-    NullCheck( Display->Font, return 0 );
-    
     if ( Character >= Display->Font->StartChar && Character <= Display->Font->EndChar ) {
     if ( Character >= Display->Font->StartChar && Character <= Display->Font->EndChar ) {
         CharPtr = GetCharPtr( Display->Font, Character );
         CharPtr = GetCharPtr( Display->Font, Character );
 
 
@@ -161,82 +143,67 @@ int SSD13x6_FontGetCharWidth( struct SSD13x6_Device* Display, char Character ) {
     return Width;
     return Width;
 }
 }
 
 
-int SSD13x6_FontGetMaxCharsPerRow( struct SSD13x6_Device* Display ) {
-    NullCheck( Display, return 0 );
-    NullCheck( Display->Font, return 0 );
-
+int GDS_FontGetMaxCharsPerRow( struct GDS_Device* Display ) {
     return Display->Width / Display->Font->Width;
     return Display->Width / Display->Font->Width;
 }
 }
 
 
-int SSD13x6_FontGetMaxCharsPerColumn( struct SSD13x6_Device* Display ) {
-    NullCheck( Display, return 0 );
-    NullCheck( Display->Font, return 0 );
-
+int GDS_FontGetMaxCharsPerColumn( struct GDS_Device* Display ) {
     return Display->Height / Display->Font->Height;    
     return Display->Height / Display->Font->Height;    
 }
 }
 
 
-int SSD13x6_FontGetCharHeight( struct SSD13x6_Device* Display ) {
-    NullCheck( Display, return 0 );
-    NullCheck( Display->Font, return 0 );
-
+int GDS_FontGetCharHeight( struct GDS_Device* Display ) {
     return Display->Font->Height;
     return Display->Font->Height;
 }
 }
 
 
-int SSD13x6_FontMeasureString( struct SSD13x6_Device* Display, const char* Text ) {
+int GDS_FontMeasureString( struct GDS_Device* Display, const char* Text ) {
     int Width = 0;
     int Width = 0;
     int Len = 0;
     int Len = 0;
 
 
-    NullCheck( Display, return 0 );
-    NullCheck( Display->Font, return 0 );
     NullCheck( Text, return 0 );
     NullCheck( Text, return 0 );
 
 
     for ( Len = strlen( Text ); Len >= 0; Len--, Text++ ) {
     for ( Len = strlen( Text ); Len >= 0; Len--, Text++ ) {
         if ( *Text >= Display->Font->StartChar && *Text <= Display->Font->EndChar ) {
         if ( *Text >= Display->Font->StartChar && *Text <= Display->Font->EndChar ) {
-            Width+= SSD13x6_FontGetCharWidth( Display, *Text );
+            Width+= GDS_FontGetCharWidth( Display, *Text );
         }
         }
     }
     }
 
 
     return Width;
     return Width;
 }
 }
 
 
-void SSD13x6_FontDrawString( struct SSD13x6_Device* Display, int x, int y, const char* Text, int Color ) {
+void GDS_FontDrawString( struct GDS_Device* Display, int x, int y, const char* Text, int Color ) {
     int Len = 0;
     int Len = 0;
     int i = 0;
     int i = 0;
 
 
-    NullCheck( Display, return );
-    NullCheck( Display->Font, return );
     NullCheck( Text, return );
     NullCheck( Text, return );
 
 
     for ( Len = strlen( Text ), i = 0; i < Len; i++ ) {
     for ( Len = strlen( Text ), i = 0; i < Len; i++ ) {
-        SSD13x6_FontDrawChar( Display, *Text, x, y, Color );
+        GDS_FontDrawChar( Display, *Text, x, y, Color );
 
 
-        x+= SSD13x6_FontGetCharWidth( Display, *Text );
+        x+= GDS_FontGetCharWidth( Display, *Text );
         Text++;
         Text++;
     }
     }
 }
 }
 
 
-void SSD13x6_FontDrawAnchoredString( struct SSD13x6_Device* Display, TextAnchor Anchor, const char* Text, int Color ) {
+void GDS_FontDrawAnchoredString( struct GDS_Device* Display, TextAnchor Anchor, const char* Text, int Color ) {
     int x = 0;
     int x = 0;
     int y = 0;
     int y = 0;
 
 
-    NullCheck( Display, return );
     NullCheck( Text, return );
     NullCheck( Text, return );
 
 
-    SSD13x6_FontGetAnchoredStringCoords( Display, &x, &y, Anchor, Text );
-    SSD13x6_FontDrawString( Display, x, y, Text, Color );
+    GDS_FontGetAnchoredStringCoords( Display, &x, &y, Anchor, Text );
+    GDS_FontDrawString( Display, x, y, Text, Color );
 }
 }
 
 
-void SSD13x6_FontGetAnchoredStringCoords( struct SSD13x6_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text ) {
+void GDS_FontGetAnchoredStringCoords( struct GDS_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text ) {
     int StringWidth = 0;
     int StringWidth = 0;
     int StringHeight = 0;
     int StringHeight = 0;
 
 
-    NullCheck( Display, return );
     NullCheck( OutX, return );
     NullCheck( OutX, return );
     NullCheck( OutY, return );
     NullCheck( OutY, return );
     NullCheck( Text, return );
     NullCheck( Text, return );
 
 
-    StringWidth = SSD13x6_FontMeasureString( Display, Text );
-    StringHeight = SSD13x6_FontGetCharHeight( Display );
+    StringWidth = GDS_FontMeasureString( Display, Text );
+    StringHeight = GDS_FontGetCharHeight( Display );
 
 
     switch ( Anchor ) {
     switch ( Anchor ) {
         case TextAnchor_East: {
         case TextAnchor_East: {

+ 91 - 0
components/display/core/gds_font.h

@@ -0,0 +1,91 @@
+#ifndef _GDS_FONT_H_
+#define _GDS_FONT_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct GDS_Device;
+
+/* 
+ * X-GLCD Font format:
+ *
+ * First byte of glyph is it's width in pixels.
+ * Each data byte represents 8 pixels going down from top to bottom.
+ * 
+ * Example glyph layout for a 16x16 font
+ * 'a': [Glyph width][Pixel column 0][Pixel column 1] where the number of pixel columns is the font height divided by 8
+ * 'b': [Glyph width][Pixel column 0][Pixel column 1]...
+ * 'c': And so on...
+ */
+ 
+struct GDS_FontDef {
+    const uint8_t* FontData;
+
+    int Width;
+    int Height;
+
+    int StartChar;
+    int EndChar;
+
+    bool Monospace;
+};
+
+typedef enum {
+    TextAnchor_East = 0,
+    TextAnchor_West,
+    TextAnchor_North,
+    TextAnchor_South,
+    TextAnchor_NorthEast,
+    TextAnchor_NorthWest,
+    TextAnchor_SouthEast,
+    TextAnchor_SouthWest,
+    TextAnchor_Center
+} TextAnchor;
+
+bool GDS_SetFont( struct GDS_Device* Display, const struct GDS_FontDef* Font );
+
+void GDS_FontForceProportional( struct GDS_Device* Display, bool Force );
+void GDS_FontForceMonospace( struct GDS_Device* Display, bool Force );
+
+int GDS_FontGetWidth( struct GDS_Device* Display );
+int GDS_FontGetHeight( struct GDS_Device* Display );
+
+int GDS_FontGetMaxCharsPerRow( struct GDS_Device* Display );
+int GDS_FontGetMaxCharsPerColumn( struct GDS_Device* Display );
+
+int GDS_FontGetCharWidth( struct GDS_Device* Display, char Character );
+int GDS_FontGetCharHeight( struct GDS_Device* Display );
+int GDS_FontMeasureString( struct GDS_Device* Display, const char* Text );\
+
+void GDS_FontDrawChar( struct GDS_Device* Display, char Character, int x, int y, int Color );
+void GDS_FontDrawString( struct GDS_Device* Display, int x, int y, const char* Text, int Color );
+void GDS_FontDrawAnchoredString( struct GDS_Device* Display, TextAnchor Anchor, const char* Text, int Color );
+void GDS_FontGetAnchoredStringCoords( struct GDS_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text );
+
+extern const struct GDS_FontDef Font_droid_sans_fallback_11x13;
+extern const struct GDS_FontDef Font_droid_sans_fallback_15x17;
+extern const struct GDS_FontDef Font_droid_sans_fallback_24x28;
+
+extern const struct GDS_FontDef Font_droid_sans_mono_7x13;
+extern const struct GDS_FontDef Font_droid_sans_mono_13x24;
+extern const struct GDS_FontDef Font_droid_sans_mono_16x31;
+
+extern const struct GDS_FontDef Font_liberation_mono_9x15;
+extern const struct GDS_FontDef Font_liberation_mono_13x21;
+extern const struct GDS_FontDef Font_liberation_mono_17x30;
+
+extern const struct GDS_FontDef Font_Tarable7Seg_16x32;
+extern const struct GDS_FontDef Font_Tarable7Seg_32x64;
+
+extern const struct GDS_FontDef Font_line_1;
+extern const struct GDS_FontDef Font_line_2;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 130 - 0
components/display/core/gds_private.h

@@ -0,0 +1,130 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "esp_attr.h"
+#include "gds.h"
+#include "gds_err.h"
+
+#define GDS_CLIPDEBUG_NONE 0
+#define GDS_CLIPDEBUG_WARNING 1
+#define GDS_CLIPDEBUG_ERROR 2
+
+#define SHADOW_BUFFER
+
+#if CONFIG_GDS_CLIPDEBUG == GDS_CLIPDEBUG_NONE
+    /*
+     * Clip silently with no console output.
+     */
+    #define ClipDebug( x, y )
+#elif CONFIG_GDS_CLIPDEBUG == GDS_CLIPDEBUG_WARNING
+    /*
+     * Log clipping to the console as a warning.
+     */
+    #define ClipDebug( x, y ) { \
+        ESP_LOGW( __FUNCTION__, "Line %d: Pixel at %d, %d CLIPPED", __LINE__, x, y ); \
+    }
+#elif CONFIG_GDS_CLIPDEBUG == GDS_CLIPDEBUG_ERROR
+    /*
+     * Log clipping as an error to the console.
+     * Also invokes an abort with stack trace.
+     */
+    #define ClipDebug( x, y ) { \
+        ESP_LOGE( __FUNCTION__, "Line %d: Pixel at %d, %d CLIPPED, ABORT", __LINE__, x, y ); \
+        abort( ); \
+    }
+#endif
+
+
+#define GDS_ALWAYS_INLINE __attribute__( ( always_inline ) )
+
+#define MAX_LINES	8
+
+#if ! defined BIT
+#define BIT( n ) ( 1 << n )
+#endif
+
+typedef enum {
+    AddressMode_Horizontal = 0,
+    AddressMode_Vertical,
+    AddressMode_Page,
+    AddressMode_Invalid
+} GDS_AddressMode;
+
+struct GDS_Device;
+struct GDS_FontDef;
+
+/*
+ * These can optionally return a succeed/fail but are as of yet unused in the driver.
+ */
+typedef bool ( *WriteCommandProc ) ( struct GDS_Device* Device, uint8_t Command );
+typedef bool ( *WriteDataProc ) ( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength );
+
+struct spi_device_t;
+typedef struct spi_device_t* spi_device_handle_t;
+
+#define IF_SPI	0
+#define IF_I2C	1
+
+struct GDS_Device {
+	uint8_t IF;
+	union {
+		// I2C Specific
+		struct {
+			uint8_t Address;
+		};
+		// SPI specific
+		struct {
+			spi_device_handle_t SPIHandle;
+			int8_t RSTPin;
+			int8_t CSPin;
+		};
+	};	
+
+    // cooked text mode
+	struct {
+		int16_t Y, Space;
+		const struct GDS_FontDef* Font;
+	} Lines[MAX_LINES];
+	
+	uint16_t Width;
+    uint16_t Height;
+	uint8_t Depth;
+		
+	uint8_t* Framebuffer, *Shadowbuffer;
+    uint16_t FramebufferSize;
+	bool Dirty;
+
+	// default fonts when using direct draw	
+	const struct GDS_FontDef* Font;
+    bool FontForceProportional;
+    bool FontForceMonospace;
+
+	// various driver-specific method
+	bool (*Init)( struct GDS_Device* Device);
+	void (*SetContrast)( struct GDS_Device* Device, uint8_t Contrast );
+	void (*DisplayOn)( struct GDS_Device* Device );
+	void (*DisplayOff)( struct GDS_Device* Device );
+	void (*Update)( struct GDS_Device* Device );
+	void (*DrawPixel)( struct GDS_Device* Device, int X, int Y, int Color );
+	void (*DrawPixelFast)( struct GDS_Device* Device, int X, int Y, int Color );
+	void (*SetHFlip)( struct GDS_Device* Device, bool On );
+	void (*SetVFlip)( struct GDS_Device* Device, bool On );
+	    
+	// interface-specific methods	
+    WriteCommandProc WriteCommand;
+    WriteDataProc WriteData;
+};
+
+bool GDS_Reset( struct GDS_Device* Device );
+
+/*
+inline void IRAM_ATTR 	GDS_DrawPixelFast( struct GDS_Device* Device, int X, int Y, int Color );
+void IRAM_ATTR 			GDS_DrawPixel( struct GDS_Device* Device, int x, int y, int Color );
+inline void IRAM_ATTR 	GDS_DrawPixel4Fast( struct GDS_Device* Device, int X, int Y, int Color );
+void IRAM_ATTR 			GDS_DrawPixel4( struct GDS_Device* Device, int x, int y, int Color );
+*/
+void IRAM_ATTR 	GDS_DrawPixelFast( struct GDS_Device* Device, int X, int Y, int Color );
+void IRAM_ATTR 			GDS_DrawPixel( struct GDS_Device* Device, int x, int y, int Color );
+void IRAM_ATTR 	GDS_DrawPixel4Fast( struct GDS_Device* Device, int X, int Y, int Color );
+void IRAM_ATTR 			GDS_DrawPixel4( struct GDS_Device* Device, int x, int y, int Color );

+ 195 - 0
components/display/core/gds_text.c

@@ -0,0 +1,195 @@
+/* 
+ *  (c) 2004,2006 Richard Titmuss for SlimProtoLib 
+ *  (c) Philippe G. 2019, philippe_44@outlook.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <stdint.h>
+#include <arpa/inet.h>
+#include "esp_log.h"
+#include "gds.h"
+#include "gds_draw.h"
+#include "gds_text.h"
+#include "gds_private.h"
+
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+static char TAG[] = "gds";
+
+/****************************************************************************************
+ *  Set fonts for each line in text mode
+ */
+static const struct GDS_FontDef *GuessFont( struct GDS_Device *Device, int FontType) {
+	switch(FontType) {
+	case GDS_FONT_LINE_1:	
+		return &Font_line_1;
+	case GDS_FONT_LINE_2:	
+		return &Font_line_2;
+	case GDS_FONT_SMALL:	
+		return &Font_droid_sans_fallback_11x13;	
+	case GDS_FONT_MEDIUM:			
+	default:		
+		return &Font_droid_sans_fallback_15x17;	
+	case GDS_FONT_LARGE:	
+		return &Font_droid_sans_fallback_24x28;
+		break;		
+	case GDS_FONT_SEGMENT:			
+		if (Device->Height == 32) return &Font_Tarable7Seg_16x32;
+		else return &Font_Tarable7Seg_32x64;
+	}
+}
+
+
+/****************************************************************************************
+ *  Set fonts for each line in text mode
+ */
+bool GDS_TextSetFontAuto(struct GDS_Device* Device, int N, int FontType, int Space) {
+	const struct GDS_FontDef *Font = GuessFont( Device, FontType );
+	return GDS_TextSetFont( Device, N, Font, Space );
+}
+
+/****************************************************************************************
+ *  Set fonts for each line in text mode
+ */
+bool GDS_TextSetFont(struct GDS_Device* Device, int N, const struct GDS_FontDef *Font, int Space) {
+	if (--N >= MAX_LINES) return false;
+
+	Device->Lines[N].Font = Font;
+	
+	// re-calculate lines absolute position
+	Device->Lines[N].Space = Space;
+	Device->Lines[0].Y = Device->Lines[0].Space;
+	for (int i = 1; i <= N; i++) Device->Lines[i].Y = Device->Lines[i-1].Y + Device->Lines[i-1].Font->Height + Device->Lines[i].Space;
+		
+	ESP_LOGI(TAG, "Adding line %u at %d (height:%u)", N + 1, Device->Lines[N].Y, Device->Lines[N].Font->Height);
+	
+	if (Device->Lines[N].Y + Device->Lines[N].Font->Height > Device->Height) {
+		ESP_LOGW(TAG, "line does not fit display");
+		return false;
+	}
+	
+	return true;
+}
+
+/****************************************************************************************
+ * 
+ */
+bool GDS_TextLine(struct GDS_Device* Device, int N, int Pos, int Attr, char *Text) {
+	int Width, X = Pos;
+
+	// counting 1..n
+	N--;
+	
+	GDS_SetFont( Device, Device->Lines[N].Font );	
+	if (Attr & GDS_TEXT_MONOSPACE) GDS_FontForceMonospace( Device, true );
+	
+	Width = GDS_FontMeasureString( Device, Text );
+	
+	// adjusting position, erase only EoL for rigth-justified
+	if (Pos == GDS_TEXT_RIGHT) X = Device->Width - Width - 1;
+	else if (Pos == GDS_TEXT_CENTER) X = (Device->Width - Width) / 2;
+	
+	// erase if requested
+	if (Attr & GDS_TEXT_CLEAR) {
+		int Y_min = max(0, Device->Lines[N].Y), Y_max = max(0, Device->Lines[N].Y + Device->Lines[N].Font->Height);
+		for (int c = (Attr & GDS_TEXT_CLEAR_EOL) ? X : 0; c < Device->Width; c++) 
+			for (int y = Y_min; y < Y_max; y++)
+				Device->DrawPixelFast( Device, c, y, GDS_COLOR_BLACK );
+	}
+		
+	GDS_FontDrawString( Device, X, Device->Lines[N].Y, Text, GDS_COLOR_WHITE );
+	
+	ESP_LOGD(TAG, "displaying %s line %u (x:%d, attr:%u)", Text, N+1, X, Attr);
+	
+	// update whole display if requested
+	Device->Dirty = true;
+	if (Attr & GDS_TEXT_UPDATE) GDS_Update( Device );
+		
+	return Width + X < Device->Width;
+}
+
+/****************************************************************************************
+ * Try to align string for better scrolling visual. there is probably much better to do
+ */
+int GDS_TextStretch(struct GDS_Device* Device, int N, char *String, int Max) {
+	char Space[] = "     ";
+	int Len = strlen(String), Extra = 0, Boundary;
+	
+	N--;
+	
+	// we might already fit
+	GDS_SetFont( Device, Device->Lines[N].Font );	
+	if (GDS_FontMeasureString( Device, String ) <= Device->Width) return 0;
+		
+	// add some space for better visual 
+	strncat(String, Space, Max-Len);
+	String[Max] = '\0';
+	Len = strlen(String);
+	
+	// mark the end of the extended string
+	Boundary = GDS_FontMeasureString( Device, String );
+			
+	// add a full display width	
+	while (Len < Max && GDS_FontMeasureString( Device, String ) - Boundary < Device->Width) {
+		String[Len++] = String[Extra++];
+		String[Len] = '\0';
+	}
+		
+	return Boundary;
+}
+
+/****************************************************************************************
+ * 
+ */
+void GDS_TextPos(struct GDS_Device* Device, int FontType, int Where, int Attr, char *Text, ...) {
+	va_list args;
+
+	TextAnchor Anchor = TextAnchor_Center;	
+	
+	if (Attr & GDS_TEXT_CLEAR) GDS_Clear( Device, GDS_COLOR_BLACK );
+	
+	if (!Text) return;
+	
+	va_start(args, Text);
+	
+	switch(Where) {
+	case GDS_TEXT_TOP_LEFT: 
+	default:
+		Anchor = TextAnchor_NorthWest; 
+		break;
+	case GDS_TEXT_MIDDLE_LEFT:
+		Anchor = TextAnchor_West;
+		break;
+	case GDS_TEXT_BOTTOM_LEFT:
+		Anchor = TextAnchor_SouthWest;
+		break;
+	case GDS_TEXT_CENTERED:
+		Anchor = TextAnchor_Center;
+		break;
+	}	
+	
+	ESP_LOGD(TAG, "Displaying %s at %u with attribute %u", Text, Anchor, Attr);
+	
+	GDS_SetFont( Device, GuessFont( Device, FontType ) );	
+	GDS_FontDrawAnchoredString( Device, Anchor, Text, GDS_COLOR_WHITE );
+	
+	Device->Dirty = true;
+	if (Attr & GDS_TEXT_UPDATE) GDS_Update( Device );
+	
+	va_end(args);
+}

+ 45 - 0
components/display/core/gds_text.h

@@ -0,0 +1,45 @@
+/* 
+ *  (c) Philippe G. 2019, philippe_44@outlook.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include "gds_font.h"
+
+#define GDS_TEXT_CLEAR 		0x01
+#define	GDS_TEXT_CLEAR_EOL	0x02
+#define GDS_TEXT_UPDATE		0x04
+#define GDS_TEXT_MONOSPACE	0x08
+
+// these ones are for 'Pos' parameter of TextLine
+#define GDS_TEXT_LEFT 	0
+#define GDS_TEXT_RIGHT	0xff00
+#define	GDS_TEXT_CENTER 0xff01
+
+// these ones are for the 'Where' parameter of TextPos
+enum { GDS_TEXT_TOP_LEFT, GDS_TEXT_MIDDLE_LEFT, GDS_TEXT_BOTTOM_LEFT, GDS_TEXT_CENTERED };
+
+enum { GDS_FONT_DEFAULT, GDS_FONT_LINE_1, GDS_FONT_LINE_2, GDS_FONT_SEGMENT, 
+	   GDS_FONT_TINY, GDS_FONT_SMALL, GDS_FONT_MEDIUM, GDS_FONT_LARGE, GDS_FONT_FONT_HUGE };
+	   
+struct GDS_Device;
+	   
+bool 	GDS_TextSetFontAuto(struct GDS_Device* Device, int N, int FontType, int Space);
+bool 	GDS_TextSetFont(struct GDS_Device* Device, int N, const struct GDS_FontDef *Font, int Space);
+bool 	GDS_TextLine(struct GDS_Device* Device, int N, int Pos, int Attr, char *Text);
+int 	GDS_TextStretch(struct GDS_Device* Device, int N, char *String, int Max);
+void 	GDS_TextPos(struct GDS_Device* Device, int FontType, int Where, int Attr, char *Text, ...);

+ 32 - 46
components/display/tarablessd13x6/ifaces/default_if_i2c.c → components/display/core/ifaces/default_if_i2c.c

@@ -11,18 +11,19 @@
 #include <string.h>
 #include <string.h>
 #include <driver/i2c.h>
 #include <driver/i2c.h>
 #include <driver/gpio.h>
 #include <driver/gpio.h>
-#include "ssd13x6.h"
-#include "ssd13x6_default_if.h"
+#include "gds.h"
+#include "gds_err.h"
+#include "gds_private.h"
+#include "gds_default_if.h"
 
 
 static int I2CPortNumber;
 static int I2CPortNumber;
 
 
-static const int SSD13x6_I2C_COMMAND_MODE = 0x80;
-static const int SSD13x6_I2C_DATA_MODE = 0x40;
+static const int GDS_I2C_COMMAND_MODE = 0x80;
+static const int GDS_I2C_DATA_MODE = 0x40;
 
 
 static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength );
 static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength );
-static bool I2CDefaultWriteCommand( struct SSD13x6_Device* Display, SSDCmd Command );
-static bool I2CDefaultWriteData( struct SSD13x6_Device* Display, const uint8_t* Data, size_t DataLength );
-static bool I2CDefaultReset( struct SSD13x6_Device* Display );
+static bool I2CDefaultWriteCommand( struct GDS_Device* Device, uint8_t Command );
+static bool I2CDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength );
 
 
 /*
 /*
  * Initializes the i2c master with the parameters specified
  * Initializes the i2c master with the parameters specified
@@ -30,7 +31,7 @@ static bool I2CDefaultReset( struct SSD13x6_Device* Display );
  * 
  * 
  * Returns true on successful init of the i2c bus.
  * Returns true on successful init of the i2c bus.
  */
  */
-bool SSD13x6_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
+bool GDS_I2CInit( int PortNumber, int SDA, int SCL ) {
 	I2CPortNumber = PortNumber;
 	I2CPortNumber = PortNumber;
 	
 	
 	if (SDA != -1 && SCL != -1) {
 	if (SDA != -1 && SCL != -1) {
@@ -54,7 +55,7 @@ bool SSD13x6_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
  * Attaches a display to the I2C bus using default communication functions.
  * Attaches a display to the I2C bus using default communication functions.
  * 
  * 
  * Params:
  * Params:
- * DisplayHandle: Pointer to your SSD13x6_Device object
+ * Device: Pointer to your GDS_Device object
  * Width: Width of display
  * Width: Width of display
  * Height: Height of display
  * Height: Height of display
  * I2CAddress: Address of your display
  * I2CAddress: Address of your display
@@ -62,26 +63,24 @@ bool SSD13x6_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
  * 
  * 
  * Returns true on successful init of display.
  * Returns true on successful init of display.
  */
  */
-bool SSD13x6_I2CMasterAttachDisplayDefault( struct SSD13x6_Device* DeviceHandle, int Model, int Width, int Height, int I2CAddress, int RSTPin ) {
-    NullCheck( DeviceHandle, return false );
-
-    if ( RSTPin >= 0 ) {
+bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int I2CAddress, int RSTPin ) {
+    NullCheck( Device, return false );
+
+    Device->WriteCommand = I2CDefaultWriteCommand;
+    Device->WriteData = I2CDefaultWriteData;
+    Device->Address = I2CAddress;
+    Device->RSTPin = RSTPin;
+	Device->IF = IF_I2C;
+	Device->Width = Width;
+	Device->Height = Height;
+	
+	if ( RSTPin >= 0 ) {
         ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
         ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
         ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 1 ), return false );
         ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 1 ), return false );
+		GDS_Reset( Device );
     }
     }
 	
 	
-	memset( DeviceHandle, 0, sizeof( struct SSD13x6_Device ) );	
-	DeviceHandle->Model = Model;
-	
-    return SSD13x6_Init_I2C( DeviceHandle,
-        Width,
-        Height,
-        I2CAddress,
-        RSTPin,
-        I2CDefaultWriteCommand,
-        I2CDefaultWriteData,
-        I2CDefaultReset
-    );
+    return Device->Init( Device );
 }
 }
 
 
 static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength ) {
 static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength ) {
@@ -91,7 +90,7 @@ static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Da
     NullCheck( Data, return false );
     NullCheck( Data, return false );
 
 
     if ( ( CommandHandle = i2c_cmd_link_create( ) ) != NULL ) {
     if ( ( CommandHandle = i2c_cmd_link_create( ) ) != NULL ) {
-        ModeByte = ( IsCommand == true ) ? SSD13x6_I2C_COMMAND_MODE: SSD13x6_I2C_DATA_MODE;
+        ModeByte = ( IsCommand == true ) ? GDS_I2C_COMMAND_MODE: GDS_I2C_DATA_MODE;
 
 
         ESP_ERROR_CHECK_NONFATAL( i2c_master_start( CommandHandle ), goto error );
         ESP_ERROR_CHECK_NONFATAL( i2c_master_start( CommandHandle ), goto error );
         ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ( Address << 1 ) | I2C_MASTER_WRITE, true ), goto error );
         ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ( Address << 1 ) | I2C_MASTER_WRITE, true ), goto error );
@@ -110,29 +109,16 @@ error:
 	return false;
 	return false;
 }
 }
 
 
-static bool I2CDefaultWriteCommand( struct SSD13x6_Device* Display, SSDCmd Command ) {
+static bool I2CDefaultWriteCommand( struct GDS_Device* Device, uint8_t Command ) {
     uint8_t CommandByte = ( uint8_t ) Command;
     uint8_t CommandByte = ( uint8_t ) Command;
-
-    NullCheck( Display, return false );
-    return I2CDefaultWriteBytes( Display->Address, true, ( const uint8_t* ) &CommandByte, 1 );
+	
+    NullCheck( Device, return false );
+    return I2CDefaultWriteBytes( Device->Address, true, ( const uint8_t* ) &CommandByte, 1 );
 }
 }
 
 
-static bool I2CDefaultWriteData( struct SSD13x6_Device* Display, const uint8_t* Data, size_t DataLength ) {
-    NullCheck( Display, return false );
+static bool I2CDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength ) {
+    NullCheck( Device, return false );
     NullCheck( Data, return false );
     NullCheck( Data, return false );
 
 
-    return I2CDefaultWriteBytes( Display->Address, false, Data, DataLength );
-}
-
-static bool I2CDefaultReset( struct SSD13x6_Device* Display ) {
-    NullCheck( Display, return false );
-
-    if ( Display->RSTPin >= 0 ) {
-        ESP_ERROR_CHECK_NONFATAL( gpio_set_level( Display->RSTPin, 0 ), return true );
-            vTaskDelay( pdMS_TO_TICKS( 100 ) );
-        ESP_ERROR_CHECK_NONFATAL( gpio_set_level( Display->RSTPin, 1 ), return true );
-    }
-
-    return true;
+    return I2CDefaultWriteBytes( Device->Address, false, Data, DataLength );
 }
 }
-

+ 109 - 0
components/display/core/ifaces/default_if_spi.c

@@ -0,0 +1,109 @@
+
+/**
+ * Copyright (c) 2017-2018 Tara Keeling
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <driver/spi_master.h>
+#include <driver/gpio.h>
+#include <freertos/task.h>
+#include "gds.h"
+#include "gds_err.h"
+#include "gds_private.h"
+#include "gds_default_if.h"
+
+static const int GDS_SPI_Command_Mode = 0;
+static const int GDS_SPI_Data_Mode = 1;
+
+static spi_host_device_t SPIHost;
+static int DCPin;
+
+static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength );
+static bool SPIDefaultWriteCommand( struct GDS_Device* Device, uint8_t Command );
+static bool SPIDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength );
+
+bool GDS_SPIInit( int SPI, int DC ) {
+	SPIHost = SPI;
+	DCPin = DC;
+    return true;
+}
+
+bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int Speed ) {
+    spi_device_interface_config_t SPIDeviceConfig;
+    spi_device_handle_t SPIDevice;
+
+    NullCheck( Device, return false );
+	
+	if (CSPin >= 0) {
+		ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( CSPin, GPIO_MODE_OUTPUT ), return false );
+		ESP_ERROR_CHECK_NONFATAL( gpio_set_level( CSPin, 0 ), return false );
+	}	
+
+    memset( &SPIDeviceConfig, 0, sizeof( spi_device_interface_config_t ) );
+
+    SPIDeviceConfig.clock_speed_hz = Speed > 0 ? Speed : SPI_MASTER_FREQ_8M;
+    SPIDeviceConfig.spics_io_num = CSPin;
+    SPIDeviceConfig.queue_size = 1;
+
+    ESP_ERROR_CHECK_NONFATAL( spi_bus_add_device( SPIHost, &SPIDeviceConfig, &SPIDevice ), return false );
+	
+	Device->WriteCommand = SPIDefaultWriteCommand;
+    Device->WriteData = SPIDefaultWriteData;
+    Device->SPIHandle = SPIDevice;
+    Device->RSTPin = RSTPin;
+    Device->CSPin = CSPin;
+	Device->IF = IF_SPI;
+	Device->Width = Width;
+	Device->Height = Height;
+	
+	if ( RSTPin >= 0 ) {
+        ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
+        ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 0 ), return false );
+		GDS_Reset( Device );
+    }
+	
+	return Device->Init( Device );
+}
+
+static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength ) {
+    spi_transaction_t SPITransaction = { 0 };
+
+    NullCheck( SPIHandle, return false );
+    NullCheck( Data, return false );
+
+    if ( DataLength > 0 ) {
+		gpio_set_level( DCPin, WriteMode );
+		
+		SPITransaction.length = DataLength * 8;
+		SPITransaction.tx_buffer = Data;
+            
+		// only do polling as we don't have contention on SPI (otherwise DMA for transfers > 16 bytes)		
+		ESP_ERROR_CHECK_NONFATAL( spi_device_polling_transmit(SPIHandle, &SPITransaction), return false );
+    }
+
+    return true;
+}
+
+static bool SPIDefaultWriteCommand( struct GDS_Device* Device, uint8_t Command ) {
+    static uint8_t CommandByte = 0;
+
+    NullCheck( Device, return false );
+    NullCheck( Device->SPIHandle, return false );
+
+    CommandByte = Command;
+
+    return SPIDefaultWriteBytes( Device->SPIHandle, GDS_SPI_Command_Mode, &CommandByte, 1 );
+}
+
+static bool SPIDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength ) {
+    NullCheck( Device, return false );
+    NullCheck( Device->SPIHandle, return false );
+
+    return SPIDefaultWriteBytes( Device->SPIHandle, GDS_SPI_Data_Mode, Data, DataLength );
+}

+ 72 - 31
components/display/display.c

@@ -22,14 +22,15 @@
 #include <stdint.h>
 #include <stdint.h>
 #include <arpa/inet.h>
 #include <arpa/inet.h>
 #include "esp_log.h"
 #include "esp_log.h"
+#include "globdefs.h"
 #include "config.h"
 #include "config.h"
 #include "tools.h"
 #include "tools.h"
 #include "display.h"
 #include "display.h"
-
-// here we should include all possible drivers
-extern struct display_s SSD13x6_display;
-
-struct display_s *display = NULL;
+#include "gds.h"
+#include "gds_default_if.h"
+#include "gds_draw.h"
+#include "gds_text.h"
+#include "gds_font.h"
 
 
 static const char *TAG = "display";
 static const char *TAG = "display";
 
 
@@ -57,34 +58,74 @@ static EXT_RAM_ATTR struct {
 
 
 static void displayer_task(void *args);
 static void displayer_task(void *args);
 
 
+struct GDS_Device *display;
+struct GDS_Device* SSD1306_Detect(char *Driver, struct GDS_Device* Device);
+struct GDS_Device* SH1106_Detect(char *Driver, struct GDS_Device* Device);
+GDS_DetectFunc drivers[] = { SH1106_Detect, SSD1306_Detect, NULL };
+
 /****************************************************************************************
 /****************************************************************************************
  * 
  * 
  */
  */
 void display_init(char *welcome) {
 void display_init(char *welcome) {
 	bool init = false;
 	bool init = false;
-	char *item = config_alloc_get(NVS_TYPE_STR, "display_config");
+	char *config = config_alloc_get(NVS_TYPE_STR, "display_config");
 
 
-	if (item && *item) {
-		char * drivername=strstr(item,"driver");
-		if (!drivername  || (drivername && (strcasestr(drivername,"SSD1306") || strcasestr(drivername,"SSD1326") || strcasestr(drivername,"SH1106")))) {
-			display = &SSD13x6_display;
-			if (display->init(item, welcome)) {
-				init = true;
-				ESP_LOGI(TAG, "Display initialization successful");
-			} else {
-				display = NULL;
-				ESP_LOGW(TAG, "Display initialization failed");
-			}
+	if (!config) {
+		ESP_LOGI(TAG, "no display");
+		return false;
+	}	
+	
+	int width = -1, height = -1;
+	char *p, *drivername = strstr(config, "driver");
+		
+	// query drivers to see if we have a match
+	ESP_LOGI(TAG, "Trying to configure display with %s", config);
+	display = GDS_AutoDetect(drivername ? drivername : "SSD1306", drivers);
+		
+	if ((p = strcasestr(config, "width")) != NULL) width = atoi(strchr(p, '=') + 1);
+	if ((p = strcasestr(config, "height")) != NULL) height = atoi(strchr(p, '=') + 1);
+		
+	// so far so good
+	if (display && width > 0 && height > 0) {
+		// Detect driver interface
+		if (strstr(config, "I2C") && i2c_system_port != -1) {
+			int address = 0x3C;
+				
+			if ((p = strcasestr(config, "address")) != NULL) address = atoi(strchr(p, '=') + 1);
+		
+			init = true;
+			GDS_I2CInit( i2c_system_port, -1, -1 ) ;
+			GDS_I2CAttachDevice( display, width, height, address, -1 );
+		
+			ESP_LOGI(TAG, "Display is I2C on port %u", address);
+		} else if (strstr(config, "SPI") && spi_system_host != -1) {
+			int CS_pin = -1, speed = 0;
+		
+			if ((p = strcasestr(config, "cs")) != NULL) CS_pin = atoi(strchr(p, '=') + 1);
+			if ((p = strcasestr(config, "speed")) != NULL) speed = atoi(strchr(p, '=') + 1);
+		
+			init = true;
+			GDS_SPIInit( spi_system_host, spi_system_dc_gpio );
+			GDS_SPIAttachDevice( display, width, height, CS_pin, -1, speed );
+				
+			ESP_LOGI(TAG, "Display is SPI host %u with cs:%d", spi_system_host, CS_pin);
 		} else {
 		} else {
-			ESP_LOGE(TAG,"Unknown display driver name in display config: %s",item);
+			display = NULL;
+			ESP_LOGI(TAG, "Unsupported display interface or serial link not configured");
 		}
 		}
 	} else {
 	} else {
-		ESP_LOGI(TAG, "no display");
-	}
+		display = NULL;
+		ESP_LOGW(TAG, "No display driver");
+	}	
 	
 	
 	if (init) {
 	if (init) {
 		static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
 		static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
 		static EXT_RAM_ATTR StackType_t xStack[DISPLAYER_STACK_SIZE] __attribute__ ((aligned (4)));
 		static EXT_RAM_ATTR StackType_t xStack[DISPLAYER_STACK_SIZE] __attribute__ ((aligned (4)));
+		
+		GDS_SetHFlip(display, strcasestr(config, "HFlip") ? true : false);
+		GDS_SetVFlip(display, strcasestr(config, "VFlip") ? true : false);
+		GDS_SetFont(display, &Font_droid_sans_fallback_15x17 );
+		GDS_TextPos(display, GDS_FONT_MEDIUM, GDS_TEXT_CENTERED, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, welcome);
 
 
 		// start the task that will handle scrolling & counting
 		// start the task that will handle scrolling & counting
 		displayer.mutex = xSemaphoreCreateMutex();
 		displayer.mutex = xSemaphoreCreateMutex();
@@ -94,13 +135,13 @@ void display_init(char *welcome) {
 		displayer.task = xTaskCreateStatic( (TaskFunction_t) displayer_task, "displayer_thread", DISPLAYER_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
 		displayer.task = xTaskCreateStatic( (TaskFunction_t) displayer_task, "displayer_thread", DISPLAYER_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
 		
 		
 		// set lines for "fixed" text mode
 		// set lines for "fixed" text mode
-		display->set_font(1, DISPLAY_FONT_LINE_1, -3);
-		display->set_font(2, DISPLAY_FONT_LINE_2, -3);
+		GDS_TextSetFontAuto(display, 1, GDS_FONT_LINE_1, -3);
+		GDS_TextSetFontAuto(display, 2, GDS_FONT_LINE_2, -3);
 		
 		
 		displayer.metadata_config = config_alloc_get(NVS_TYPE_STR, "metadata_config");
 		displayer.metadata_config = config_alloc_get(NVS_TYPE_STR, "metadata_config");
 	}
 	}
 	
 	
-	if (item) free(item);
+	free(config);
 }
 }
 
 
 /****************************************************************************************
 /****************************************************************************************
@@ -114,14 +155,14 @@ static void displayer_task(void *args) {
 	while (1) {
 	while (1) {
 		// suspend ourselves if nothing to do
 		// suspend ourselves if nothing to do
 		if (displayer.state < DISPLAYER_ACTIVE) {
 		if (displayer.state < DISPLAYER_ACTIVE) {
-			if (displayer.state == DISPLAYER_IDLE) display->line(2, 0, DISPLAY_CLEAR | DISPLAY_UPDATE, displayer.string);
+			if (displayer.state == DISPLAYER_IDLE) GDS_TextLine(display, 2, 0, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, displayer.string);
 			vTaskSuspend(NULL);
 			vTaskSuspend(NULL);
 			scroll_sleep = 0;
 			scroll_sleep = 0;
-			display->clear(true);
-			display->line(1, DISPLAY_LEFT, DISPLAY_UPDATE, displayer.header);
+			GDS_ClearExt(display, true);
+			GDS_TextLine(display, 1, GDS_TEXT_LEFT, GDS_TEXT_UPDATE, displayer.header);
 		} else if (displayer.refresh) {
 		} else if (displayer.refresh) {
 			// little trick when switching master while in IDLE and missing it
 			// little trick when switching master while in IDLE and missing it
-			display->line(1, DISPLAY_LEFT, DISPLAY_CLEAR | DISPLAY_UPDATE, displayer.header);	
+			GDS_TextLine(display, 1, GDS_TEXT_LEFT, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, displayer.header);	
 			displayer.refresh = false;			
 			displayer.refresh = false;			
 		}
 		}
 		
 		
@@ -140,7 +181,7 @@ static void displayer_task(void *args) {
 				xSemaphoreGive(displayer.mutex);				
 				xSemaphoreGive(displayer.mutex);				
 				
 				
 				// now display using safe copies, can be lengthy
 				// now display using safe copies, can be lengthy
-				display->line(2, offset, DISPLAY_CLEAR | DISPLAY_UPDATE, string);
+				GDS_TextLine(display, 2, offset, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, string);
 				free(string);
 				free(string);
 			} else {
 			} else {
 				scroll_sleep = DEFAULT_SLEEP;
 				scroll_sleep = DEFAULT_SLEEP;
@@ -160,7 +201,7 @@ static void displayer_task(void *args) {
 				xSemaphoreGive(displayer.mutex);				
 				xSemaphoreGive(displayer.mutex);				
 				if (displayer.elapsed < 3600) sprintf(counter, "%5u:%02u", displayer.elapsed / 60, displayer.elapsed % 60);
 				if (displayer.elapsed < 3600) sprintf(counter, "%5u:%02u", displayer.elapsed / 60, displayer.elapsed % 60);
 				else sprintf(counter, "%2u:%02u:%02u", displayer.elapsed / 3600, (displayer.elapsed % 3600) / 60, displayer.elapsed % 60);
 				else sprintf(counter, "%2u:%02u:%02u", displayer.elapsed / 3600, (displayer.elapsed % 3600) / 60, displayer.elapsed % 60);
-				display->line(1, DISPLAY_RIGHT, (DISPLAY_CLEAR | DISPLAY_ONLY_EOL) | DISPLAY_UPDATE, counter);
+				GDS_TextLine(display, 1, GDS_TEXT_RIGHT, (GDS_TEXT_CLEAR | GDS_TEXT_CLEAR_EOL) | GDS_TEXT_UPDATE, counter);
 				timer_sleep = 1000;
 				timer_sleep = 1000;
 			} else timer_sleep = max(1000 - elapsed, 0);	
 			} else timer_sleep = max(1000 - elapsed, 0);	
 		} else timer_sleep = DEFAULT_SLEEP;
 		} else timer_sleep = DEFAULT_SLEEP;
@@ -240,7 +281,7 @@ void displayer_metadata(char *artist, char *album, char *title) {
 	displayer.offset = 0;	
 	displayer.offset = 0;	
 	utf8_decode(displayer.string);
 	utf8_decode(displayer.string);
 	ESP_LOGI(TAG, "playing %s", displayer.string);
 	ESP_LOGI(TAG, "playing %s", displayer.string);
-	displayer.boundary = display->stretch(2, displayer.string, SCROLLABLE_SIZE);
+	displayer.boundary = GDS_TextStretch(display, 2, displayer.string, SCROLLABLE_SIZE);
 		
 		
 	xSemaphoreGive(displayer.mutex);
 	xSemaphoreGive(displayer.mutex);
 }	
 }	
@@ -258,7 +299,7 @@ void displayer_scroll(char *string, int speed) {
 	displayer.offset = 0;	
 	displayer.offset = 0;	
 	strncpy(displayer.string, string, SCROLLABLE_SIZE);
 	strncpy(displayer.string, string, SCROLLABLE_SIZE);
 	displayer.string[SCROLLABLE_SIZE] = '\0';
 	displayer.string[SCROLLABLE_SIZE] = '\0';
-	displayer.boundary = display->stretch(2, displayer.string, SCROLLABLE_SIZE);
+	displayer.boundary = GDS_TextStretch(display, 2, displayer.string, SCROLLABLE_SIZE);
 		
 		
 	xSemaphoreGive(displayer.mutex);
 	xSemaphoreGive(displayer.mutex);
 }
 }

+ 3 - 34
components/display/display.h

@@ -18,6 +18,8 @@
 
 
 #pragma once
 #pragma once
 
 
+#include "gds.h"
+
 /* 
 /* 
  The displayer is not thread-safe and the caller must ensure use its own 
  The displayer is not thread-safe and the caller must ensure use its own 
  mutexes if it wants something better. Especially, text() line() and draw()
  mutexes if it wants something better. Especially, text() line() and draw()
@@ -32,44 +34,11 @@
  when this one (the main) wants to take control over display, it can signal
  when this one (the main) wants to take control over display, it can signal
  that to others
  that to others
 */ 
 */ 
+extern struct GDS_Device *display;
   
   
-#define DISPLAY_CLEAR 		0x01
-#define	DISPLAY_ONLY_EOL	0x02
-#define DISPLAY_UPDATE		0x04
-#define DISPLAY_MONOSPACE	0x08
-
-// these ones are for 'x' parameter of line() function
-#define DISPLAY_LEFT 	0
-#define DISPLAY_RIGHT	0xff00
-#define	DISPLAY_CENTER  0xff01
-
-enum display_pos_e 	{ DISPLAY_TOP_LEFT, DISPLAY_MIDDLE_LEFT, DISPLAY_BOTTOM_LEFT, DISPLAY_CENTERED };
-enum display_font_e { DISPLAY_FONT_DEFAULT, 
-					  DISPLAY_FONT_LINE_1, DISPLAY_FONT_LINE_2, DISPLAY_FONT_SEGMENT, 
-					  DISPLAY_FONT_TINY, DISPLAY_FONT_SMALL,  DISPLAY_FONT_MEDIUM, DISPLAY_FONT_LARGE, DISPLAY_FONT_HUGE };
-					  
 enum displayer_cmd_e 	{ DISPLAYER_SHUTDOWN, DISPLAYER_ACTIVATE, DISPLAYER_SUSPEND, DISPLAYER_TIMER_PAUSE, DISPLAYER_TIMER_RUN };
 enum displayer_cmd_e 	{ DISPLAYER_SHUTDOWN, DISPLAYER_ACTIVATE, DISPLAYER_SUSPEND, DISPLAYER_TIMER_PAUSE, DISPLAYER_TIMER_RUN };
 enum displayer_time_e 	{ DISPLAYER_ELAPSED, DISPLAYER_REMAINING };
 enum displayer_time_e 	{ DISPLAYER_ELAPSED, DISPLAYER_REMAINING };
 
 
-// don't change anything there w/o changing all drivers init code
-extern struct display_s {
-	int width, height;
-	bool dirty;
-	bool (*init)(char *config, char *welcome);
-	void (*clear)(bool full, ...);
-	bool (*set_font)(int num, enum display_font_e font, int space);
-	void (*on)(bool state);
-	void (*brightness)(uint8_t level);
-	void (*text)(enum display_font_e font, enum display_pos_e pos, int attribute, char *msg, ...);
-	bool (*line)(int num, int x, int attribute, char *text);
-	int (*stretch)(int num, char *string, int max);
-	void (*update)(void);
-	void (*draw_raw)(int x1, int y1, int x2, int y2, bool by_column, bool MSb, uint8_t *data);
-	void (*draw_cbr)(uint8_t *data, int width, int height);		// width and height is the # of rows/columns in data, as opposed to display height (0 = display width, 0 = display height) 
-	void (*draw_line)(int x1, int y1, int x2, int y2);
-	void (*draw_box)( int x1, int y1, int x2, int y2, bool fill);
-} *display;
-
 enum display_bus_cmd_e { DISPLAY_BUS_TAKE, DISPLAY_BUS_GIVE };
 enum display_bus_cmd_e { DISPLAY_BUS_TAKE, DISPLAY_BUS_GIVE };
 bool (*display_bus)(void *from, enum display_bus_cmd_e cmd);
 bool (*display_bus)(void *from, enum display_bus_cmd_e cmd);
 
 

+ 0 - 446
components/display/driver_SSD13x6.c

@@ -1,446 +0,0 @@
-/* 
- *  (c) 2004,2006 Richard Titmuss for SlimProtoLib 
- *  (c) Philippe G. 2019, philippe_44@outlook.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <string.h>
-#include <ctype.h>
-#include <stdint.h>
-#include <arpa/inet.h>
-#include "esp_log.h"
-#include "display.h"
-#include "globdefs.h"
-
-#include "ssd13x6.h"
-#include "ssd13x6_draw.h"
-#include "ssd13x6_font.h"
-#include "ssd13x6_default_if.h"
-
-#define I2C_ADDRESS	0x3C
-
-static const char *TAG = "display";
-
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-// handlers
-static bool init(char *config, char *welcome);
-static void clear(bool full, ...);
-static bool set_font(int num, enum display_font_e font, int space);
-static void text(enum display_font_e font, enum display_pos_e pos, int attribute, char *text, ...);
-static bool line(int num, int x, int attribute, char *text);
-static int stretch(int num, char *string, int max);
-static void draw_cbr(u8_t *data, int width, int height);
-static void draw_raw(int x1, int y1, int x2, int y2, bool by_column, bool MSb, u8_t *data);
-static void draw_line(int x1, int y1, int x2, int y2);
-static void draw_box( int x1, int y1, int x2, int y2, bool fill);
-static void brightness(u8_t level);
-static void on(bool state);
-static void update(void);
-
-// display structure for others to use
-struct display_s SSD13x6_display = { 0, 0, true,
-									init, clear, set_font, on, brightness, 
-									text, line, stretch, update, draw_raw, draw_cbr, draw_line, draw_box };
-
-// SSD13x6 specific function
-static struct SSD13x6_Device Display;
-
-static const unsigned char BitReverseTable256[] = 
-{
-  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
-  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
-  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
-  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
-  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
-  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
-  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
-  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
-  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
-  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
-  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
-  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
-  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
-  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
-  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
-  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
-};
-
-#define MAX_LINES	8
-
-static struct {
-	int y, space;
-	const struct SSD13x6_FontDef *font;
-} lines[MAX_LINES];
-
-/****************************************************************************************
- * 
- */
-static bool init(char *config, char *welcome) {
-	bool res = true;
-	int width = -1, height = -1, model = SSD1306;
-	char *p;
-	
-	ESP_LOGI(TAG, "Initializing display with config: %s",config);
-	
-	// no time for smart parsing - this is for tinkerers
-	if ((p = strcasestr(config, "width")) != NULL) width = atoi(strchr(p, '=') + 1);
-	if ((p = strcasestr(config, "height")) != NULL) height = atoi(strchr(p, '=') + 1);
-	
-	if (strcasestr(config, "ssd1326")) model = SSD1326;
-	else if (strcasestr(config, "sh1106")) model = SH1106;
-	
-	if (width == -1 || height == -1) {
-		ESP_LOGW(TAG, "No display configured %s [%d x %d]", config, width, height);
-		return false;
-	}	
-
-	if (strstr(config, "I2C") && i2c_system_port != -1) {
-		int address = I2C_ADDRESS;
-				
-		if ((p = strcasestr(config, "address")) != NULL) address = atoi(strchr(p, '=') + 1);
-		
-		SSD13x6_I2CMasterInitDefault( i2c_system_port, -1, -1 ) ;
-		SSD13x6_I2CMasterAttachDisplayDefault( &Display, model, width, height, address, -1 );
-		SSD13x6_SetHFlip( &Display, strcasestr(config, "HFlip") ? true : false);
-		SSD13x6_SetVFlip( &Display, strcasestr(config, "VFlip") ? true : false);
-		SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_15x17 );
-		SSD13x6_display.width = width;
-		SSD13x6_display.height = height;
-		
-		text(DISPLAY_FONT_MEDIUM, DISPLAY_CENTERED, DISPLAY_CLEAR | DISPLAY_UPDATE, welcome);
-		
-		ESP_LOGI(TAG, "Display is I2C on port %u", address);
-	} else if (strstr(config, "SPI") && spi_system_host != -1) {
-		int CS_pin = -1, speed = 0;
-		
-		if ((p = strcasestr(config, "cs")) != NULL) CS_pin = atoi(strchr(p, '=') + 1);
-		if ((p = strcasestr(config, "speed")) != NULL) speed = atoi(strchr(p, '=') + 1);
-		
-		SSD13x6_SPIMasterInitDefault( spi_system_host, spi_system_dc_gpio );
-        SSD13x6_SPIMasterAttachDisplayDefault( &Display, model, width, height, CS_pin, -1, speed );
-		SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_15x17 );
-		SSD13x6_display.width = width;
-		SSD13x6_display.height = height;
-		
-		text(DISPLAY_FONT_MEDIUM, DISPLAY_CENTERED, DISPLAY_CLEAR | DISPLAY_UPDATE, welcome);
-		
-		ESP_LOGI(TAG, "Display is SPI host %u with cs:%d", spi_system_host, CS_pin);
-		
-	} else {
-		res = false;
-		ESP_LOGW(TAG, "Unknown display type or no serial interface configured");
-	}
-
-	return res;
-}
-
-/****************************************************************************************
- * 
- */
-static void clear(bool full, ...) {
-	bool commit = true;
-	
-	if (full) {
-		SSD13x6_Clear( &Display, SSD_COLOR_BLACK ); 
-	} else {
-		va_list args;
-		va_start(args, full);
-		commit = va_arg(args, int);
-		int x1 = va_arg(args, int), y1 = va_arg(args, int), x2 = va_arg(args, int), y2 = va_arg(args, int);
-		if (x2 < 0) x2 = display->width - 1;
-		if (y2 < 0) y2 = display->height - 1;
-		SSD13x6_ClearWindow( &Display, x1, y1, x2, y2, SSD_COLOR_BLACK );
-		va_end(args);
-	}
-	
-	SSD13x6_display.dirty = true;
-	if (commit)	update();		
-}	
-
-/****************************************************************************************
- *  Set fonts for each line in text mode
- */
-static bool set_font(int num, enum display_font_e font, int space) {
-	if (--num >= MAX_LINES) return false;
-	
-	switch(font) {
-	case DISPLAY_FONT_LINE_1:	
-		lines[num].font = &Font_line_1;
-		break;
-	case DISPLAY_FONT_LINE_2:	
-		lines[num].font = &Font_line_2;
-		break;		
-	case DISPLAY_FONT_SMALL:	
-		lines[num].font = &Font_droid_sans_fallback_11x13;	
-		break;
-	case DISPLAY_FONT_MEDIUM:			
-	case DISPLAY_FONT_DEFAULT:
-	default:		
-		lines[num].font = &Font_droid_sans_fallback_15x17;	
-		break;
-	case DISPLAY_FONT_LARGE:	
-		lines[num].font = &Font_droid_sans_fallback_24x28;
-		break;		
-	case DISPLAY_FONT_SEGMENT:			
-		if (Display.Height == 32) lines[num].font = &Font_Tarable7Seg_16x32;
-		else lines[num].font = &Font_Tarable7Seg_32x64;
-		break;		
-	}
-	
-	// re-calculate lines absolute position
-	lines[num].space = space;
-	lines[0].y = lines[0].space;
-	for (int i = 1; i <= num; i++) lines[i].y = lines[i-1].y + lines[i-1].font->Height + lines[i].space;
-		
-	ESP_LOGI(TAG, "Adding line %u at %d (height:%u)", num + 1, lines[num].y, lines[num].font->Height);
-	
-	if (lines[num].y + lines[num].font->Height > Display.Height) {
-		ESP_LOGW(TAG, "line does not fit display");
-		return false;
-	}
-	
-	return true;
-}
-
-/****************************************************************************************
- * 
- */
-static bool line(int num, int x, int attribute, char *text) {
-	int width;
-
-	// counting 1..n
-	num--;
-	
-	SSD13x6_SetFont( &Display, lines[num].font );	
-	if (attribute & DISPLAY_MONOSPACE) SSD13x6_FontForceMonospace( &Display, true );
-	
-	width = SSD13x6_FontMeasureString( &Display, text );
-	
-	// adjusting position, erase only EoL for rigth-justified
-	if (x == DISPLAY_RIGHT) x = Display.Width - width - 1;
-	else if (x == DISPLAY_CENTER) x = (Display.Width - width) / 2;
-	
-	// erase if requested
-	if (attribute & DISPLAY_CLEAR) {
-		int y_min = max(0, lines[num].y), y_max = max(0, lines[num].y + lines[num].font->Height);
-		for (int c = (attribute & DISPLAY_ONLY_EOL) ? x : 0; c < Display.Width; c++) 
-			for (int y = y_min; y < y_max; y++)
-				SSD13x6_DrawPixelFast( &Display, c, y, SSD_COLOR_BLACK );
-	}
-		
-	SSD13x6_FontDrawString( &Display, x, lines[num].y, text, SSD_COLOR_WHITE );
-	
-	ESP_LOGD(TAG, "displaying %s line %u (x:%d, attr:%u)", text, num+1, x, attribute);
-	
-	// update whole display if requested
-	SSD13x6_display.dirty = true;
-	if (attribute & DISPLAY_UPDATE) update();
-		
-	return width + x < Display.Width;
-}
-
-/****************************************************************************************
- * Try to align string for better scrolling visual. there is probably much better to do
- */
-static int stretch(int num, char *string, int max) {
-	char space[] = "     ";
-	int len = strlen(string), extra = 0, boundary;
-	
-	num--;
-	
-	// we might already fit
-	SSD13x6_SetFont( &Display, lines[num].font );	
-	if (SSD13x6_FontMeasureString( &Display, string ) <= Display.Width) return 0;
-		
-	// add some space for better visual 
-	strncat(string, space, max-len);
-	string[max] = '\0';
-	len = strlen(string);
-	
-	// mark the end of the extended string
-	boundary = SSD13x6_FontMeasureString( &Display, string );
-			
-	// add a full display width	
-	while (len < max && SSD13x6_FontMeasureString( &Display, string ) - boundary < Display.Width) {
-		string[len++] = string[extra++];
-		string[len] = '\0';
-	}
-		
-	return boundary;
-}
-
-/****************************************************************************************
- * 
- */
-static void text(enum display_font_e font, enum display_pos_e pos, int attribute, char *text, ...) {
-	va_list args;
-
-	TextAnchor Anchor = TextAnchor_Center;	
-	
-	if (attribute & DISPLAY_CLEAR) SSD13x6_Clear( &Display, SSD_COLOR_BLACK );
-	
-	if (!text) return;
-	
-	va_start(args, text);
-	
-	switch(font) {
-	case DISPLAY_FONT_LINE_1:	
-		SSD13x6_SetFont( &Display, &Font_line_1 );
-		break;
-	case DISPLAY_FONT_LINE_2:	
-		SSD13x6_SetFont( &Display, &Font_line_2 );
-		break;		
-	case DISPLAY_FONT_SMALL:	
-		SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_11x13 );	
-		break;	
-	case DISPLAY_FONT_MEDIUM:			
-	case DISPLAY_FONT_DEFAULT:
-	default:
-		SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_15x17 );	
-		break;		
-	case DISPLAY_FONT_LARGE:	
-		SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_24x28 );
-		break;		
-	case DISPLAY_FONT_SEGMENT:			
-		if (Display.Height == 32) SSD13x6_SetFont( &Display, &Font_Tarable7Seg_16x32 );
-		else SSD13x6_SetFont( &Display, &Font_Tarable7Seg_32x64 );
-		break;		
-	}
-
-	switch(pos) {
-	case DISPLAY_TOP_LEFT: 
-	default:
-		Anchor = TextAnchor_NorthWest; 
-		break;
-	case DISPLAY_MIDDLE_LEFT:
-		Anchor = TextAnchor_West;
-		break;
-	case DISPLAY_BOTTOM_LEFT:
-		Anchor = TextAnchor_SouthWest;
-		break;
-	case DISPLAY_CENTERED:
-		Anchor = TextAnchor_Center;
-		break;
-	}	
-	
-	ESP_LOGD(TAG, "SSDD13x6 displaying %s at %u with attribute %u", text, Anchor, attribute);
-	
-	SSD13x6_FontDrawAnchoredString( &Display, Anchor, text, SSD_COLOR_WHITE );
-	
-	SSD13x6_display.dirty = true;
-	if (attribute & DISPLAY_UPDATE) update();
-	
-	va_end(args);
-}
-
-/****************************************************************************************
- * Process graphic display data from column-oriented data (MSbit first)
- */
-static void draw_cbr(u8_t *data, int width, int height) {
-	if (!height) height = Display.Height;
-	if (!width) width = Display.Width;
-
-	// need to do row/col swap and bit-reverse
-	int rows = height / 8;
-	for (int r = 0; r < rows; r++) {
-		uint8_t *optr = Display.Framebuffer + r*Display.Width, *iptr = data + r;
-		for (int c = width; --c >= 0;) {
-			*optr++ = BitReverseTable256[*iptr];;
-			iptr += rows;
-		}	
-	}
-	
-	SSD13x6_display.dirty = true;
-}
-
-/****************************************************************************************
- * Process graphic display data MSBit first
- * WARNING: this has not been tested yet
- */
-static void draw_raw(int x1, int y1, int x2, int y2, bool by_column, bool MSb, u8_t *data) {
-	// default end point to display size
-	if (x2 == -1) x2 = Display.Width - 1;
-	if (y2 == -1) y2 = Display.Height - 1;
-	
-	display->dirty = true;
-	
-	//	not a boundary draw
-	if (y1 % 8 || y2 % 8 || x1 % 8 | x2 % 8) {
-		ESP_LOGW(TAG, "can't write on non cols/rows boundaries for now");
-	} else {	
-		// set addressing mode to match data
-		if (by_column) {
-			// copy the window and do row/col exchange
-			for (int r = y1/8; r <=  y2/8; r++) {
-				uint8_t *optr = Display.Framebuffer + r*Display.Width + x1, *iptr = data + r;
-				for (int c = x1; c <= x2; c++) {
-					*optr++ = MSb ? BitReverseTable256[*iptr] : *iptr;
-					iptr += (y2-y1)/8 + 1;
-			}	
-			}	
-		} else {
-			// just copy the window inside the frame buffer
-			for (int r = y1/8; r <= y2/8; r++) {
-				uint8_t *optr = Display.Framebuffer + r*Display.Width + x1, *iptr = data + r*(x2-x1+1);
-				for (int c = x1; c <= x2; c++) *optr++ = *iptr++;
-			}	
-		}
-	}	
-}
-
-/****************************************************************************************
- * Draw line
- */
-static void draw_line( int x1, int y1, int x2, int y2) {
-	SSD13x6_DrawLine( &Display, x1, y1, x2, y2, SSD_COLOR_WHITE );
-	SSD13x6_display.dirty = true;
-}
-
-/****************************************************************************************
- * Draw Box
- */
-static void draw_box( int x1, int y1, int x2, int y2, bool fill) {
-	SSD13x6_DrawBox( &Display, x1, y1, x2, y2, SSD_COLOR_WHITE, fill );
-	SSD13x6_display.dirty = true;
-}
-
-/****************************************************************************************
- * Brightness
- */
-static void brightness(u8_t level) {
-	SSD13x6_DisplayOn( &Display ); 
-	SSD13x6_SetContrast( &Display, (uint8_t) level);
-}
-
-/****************************************************************************************
- * Display On/Off
- */
-static void on(bool state) {
-	if (state) SSD13x6_DisplayOn( &Display ); 
-	else SSD13x6_DisplayOff( &Display ); 
-}
-
-/****************************************************************************************
- * Update 
- */
-static void update(void) {
-	if (SSD13x6_display.dirty) SSD13x6_Update( &Display );
-	SSD13x6_display.dirty = false;
-}
-
-
-

+ 0 - 0
components/display/tarablessd13x6/fonts/LICENSE-apache → components/display/fonts/LICENSE-apache


+ 0 - 0
components/display/tarablessd13x6/fonts/LICENSE-liberation-mono → components/display/fonts/LICENSE-liberation-mono


+ 2 - 2
components/display/tarablessd13x6/fonts/font_droid_sans_fallback_11x13.c → components/display/fonts/font_droid_sans_fallback_11x13.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Fallback11x13[ ] = {
     0x05, 0x00, 0x10, 0xE4, 0x11, 0x00, 0x0E, 0x00, 0x02, 0xE4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
     0x05, 0x00, 0x10, 0xE4, 0x11, 0x00, 0x0E, 0x00, 0x02, 0xE4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_droid_sans_fallback_11x13 = {
+const struct GDS_FontDef Font_droid_sans_fallback_11x13 = {
     Droid_Sans_Fallback11x13,
     Droid_Sans_Fallback11x13,
     11,
     11,
     13,
     13,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_droid_sans_fallback_15x17.c → components/display/fonts/font_droid_sans_fallback_15x17.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Fallback15x17[ ] = {
     0x07, 0xC0, 0x00, 0x01, 0x00, 0x03, 0x01, 0x10, 0x8C, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
     0x07, 0xC0, 0x00, 0x01, 0x00, 0x03, 0x01, 0x10, 0x8C, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_droid_sans_fallback_15x17 = {
+const struct GDS_FontDef Font_droid_sans_fallback_15x17 = {
     Droid_Sans_Fallback15x17,
     Droid_Sans_Fallback15x17,
     15,
     15,
     17,
     17,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_droid_sans_fallback_24x28.c → components/display/fonts/font_droid_sans_fallback_24x28.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Fallback24x28[ ] = {
     0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x0C, 0xE0, 0xF0, 0x03, 0x0C, 0xE0, 0x80, 0x0F, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x7E, 0x00, 0xE0, 0x80, 0x0F, 0x00, 0xE0, 0xF0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
     0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x0C, 0xE0, 0xF0, 0x03, 0x0C, 0xE0, 0x80, 0x0F, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x7E, 0x00, 0xE0, 0x80, 0x0F, 0x00, 0xE0, 0xF0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_droid_sans_fallback_24x28 = {
+const struct GDS_FontDef Font_droid_sans_fallback_24x28 = {
     Droid_Sans_Fallback24x28,
     Droid_Sans_Fallback24x28,
     24,
     24,
     28,
     28,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_droid_sans_mono_13x24.c → components/display/fonts/font_droid_sans_mono_13x24.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Mono13x24[ ] = {
     0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x80, 0x07, 0xC0, 0x00, 0x1E, 0xC0, 0x18, 0xF8, 0xC0, 0x18, 0xC0, 0x7F, 0x00, 0x00, 0x1E, 0x00, 0xC0, 0x07, 0x18, 0xF8, 0x00, 0x18, 0x3E, 0x00, 0x80, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
     0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x80, 0x07, 0xC0, 0x00, 0x1E, 0xC0, 0x18, 0xF8, 0xC0, 0x18, 0xC0, 0x7F, 0x00, 0x00, 0x1E, 0x00, 0xC0, 0x07, 0x18, 0xF8, 0x00, 0x18, 0x3E, 0x00, 0x80, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_droid_sans_mono_13x24 = {
+const struct GDS_FontDef Font_droid_sans_mono_13x24 = {
     Droid_Sans_Mono13x24,
     Droid_Sans_Mono13x24,
     13,
     13,
     24,
     24,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_droid_sans_mono_16x31.c → components/display/fonts/font_droid_sans_mono_16x31.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Mono16x31[ ] = {
     0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00, 0x78, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x60, 0x00, 0xE0, 0x07, 0x60, 0xE0, 0x00, 0x3F, 0x70, 0xE0, 0x00, 0xFC, 0x3C, 0x40, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x40, 0x00, 0xF8, 0x01, 0xE0, 0x00, 0x3F, 0x00, 0xE0, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
     0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00, 0x78, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x60, 0x00, 0xE0, 0x07, 0x60, 0xE0, 0x00, 0x3F, 0x70, 0xE0, 0x00, 0xFC, 0x3C, 0x40, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x40, 0x00, 0xF8, 0x01, 0xE0, 0x00, 0x3F, 0x00, 0xE0, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_droid_sans_mono_16x31 = {
+const struct GDS_FontDef Font_droid_sans_mono_16x31 = {
     Droid_Sans_Mono16x31,
     Droid_Sans_Mono16x31,
     16,
     16,
     31,
     31,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_droid_sans_mono_7x13.c → components/display/fonts/font_droid_sans_mono_7x13.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Mono7x13[ ] = {
     0x06, 0x00, 0x00, 0x30, 0x10, 0xC4, 0x10, 0x00, 0x0F, 0xC4, 0x01, 0x30, 0x00, 0x00, 0x00  // Code for char ÿ
     0x06, 0x00, 0x00, 0x30, 0x10, 0xC4, 0x10, 0x00, 0x0F, 0xC4, 0x01, 0x30, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_droid_sans_mono_7x13 = {
+const struct GDS_FontDef Font_droid_sans_mono_7x13 = {
     Droid_Sans_Mono7x13,
     Droid_Sans_Mono7x13,
     7,
     7,
     13,
     13,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_liberation_mono_13x21.c → components/display/fonts/font_liberation_mono_13x21.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Liberation_Mono13x21[ ] = {
     0x0C, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x03, 0x10, 0x00, 0x0F, 0x10, 0x0C, 0x3C, 0x18, 0x00, 0xE0, 0x0D, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x0C, 0x3C, 0x00, 0x00, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
     0x0C, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x03, 0x10, 0x00, 0x0F, 0x10, 0x0C, 0x3C, 0x18, 0x00, 0xE0, 0x0D, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x0C, 0x3C, 0x00, 0x00, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_liberation_mono_13x21 = {
+const struct GDS_FontDef Font_liberation_mono_13x21 = {
     Liberation_Mono13x21,
     Liberation_Mono13x21,
     13,
     13,
     21,
     21,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_liberation_mono_17x30.c → components/display/fonts/font_liberation_mono_17x30.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Liberation_Mono17x30[] = {
     0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x30, 0x00, 0x3F, 0x00, 0x30, 0x00, 0xFC, 0x01, 0x30, 0x38, 0xE0, 0x07, 0x38, 0x38, 0x00, 0x3F, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x38, 0x00, 0x3F, 0x00, 0x38, 0xE0, 0x07, 0x00, 0x38, 0xFC, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
     0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x30, 0x00, 0x3F, 0x00, 0x30, 0x00, 0xFC, 0x01, 0x30, 0x38, 0xE0, 0x07, 0x38, 0x38, 0x00, 0x3F, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x38, 0x00, 0x3F, 0x00, 0x38, 0xE0, 0x07, 0x00, 0x38, 0xFC, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_liberation_mono_17x30 = {
+const struct GDS_FontDef Font_liberation_mono_17x30 = {
     Liberation_Mono17x30,
     Liberation_Mono17x30,
     17,
     17,
     30,
     30,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_liberation_mono_9x15.c → components/display/fonts/font_liberation_mono_9x15.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Liberation_Mono9x15[ ] = {
     0x08, 0x00, 0x00, 0x30, 0x40, 0xC6, 0x41, 0x06, 0x67, 0x00, 0x18, 0x06, 0x07, 0xC6, 0x01, 0x30, 0x00, 0x00, 0x00  // Code for char ÿ
     0x08, 0x00, 0x00, 0x30, 0x40, 0xC6, 0x41, 0x06, 0x67, 0x00, 0x18, 0x06, 0x07, 0xC6, 0x01, 0x30, 0x00, 0x00, 0x00  // Code for char ÿ
 };
 };
 
 
-const struct SSD13x6_FontDef Font_liberation_mono_9x15 = {
+const struct GDS_FontDef Font_liberation_mono_9x15 = {
     Liberation_Mono9x15,
     Liberation_Mono9x15,
     9,
     9,
     15,
     15,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_line_1.c → components/display/fonts/font_line_1.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -214,7 +214,7 @@ static const uint8_t Square721_BT11x14[] = {
         0x06, 0x00, 0x00, 0xE8, 0x03, 0xB0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Code for char è
         0x06, 0x00, 0x00, 0xE8, 0x03, 0xB0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Code for char è
         };
         };
 
 
-const struct SSD13x6_FontDef Font_line_1 = {
+const struct GDS_FontDef Font_line_1 = {
     Square721_BT11x14,
     Square721_BT11x14,
     11,
     11,
     14,
     14,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_line_2.c → components/display/fonts/font_line_2.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Archivo_Narrow18x24[] = {
         0x0A, 0x00, 0x01, 0x00, 0x00, 0x1F, 0xE0, 0x38, 0xFF, 0xE0, 0x38, 0xFC, 0xF7, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x3F, 0x38, 0xF0, 0x0F, 0x38, 0xFF, 0x01, 0x00, 0x1F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Code for char ÿ
         0x0A, 0x00, 0x01, 0x00, 0x00, 0x1F, 0xE0, 0x38, 0xFF, 0xE0, 0x38, 0xFC, 0xF7, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x3F, 0x38, 0xF0, 0x0F, 0x38, 0xFF, 0x01, 0x00, 0x1F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Code for char ÿ
         };
         };
 				
 				
-const struct SSD13x6_FontDef Font_line_2 = {
+const struct GDS_FontDef Font_line_2 = {
     Archivo_Narrow18x24,
     Archivo_Narrow18x24,
     18,
     18,
     24,
     24,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_tarable7seg_16x32.c → components/display/fonts/font_tarable7seg_16x32.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -109,7 +109,7 @@ static const uint8_t Tarable7Seg_16x32[ ] = {
     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char 
     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char 
 };
 };
 
 
-const struct SSD13x6_FontDef Font_Tarable7Seg_16x32 = {
+const struct GDS_FontDef Font_Tarable7Seg_16x32 = {
     Tarable7Seg_16x32,
     Tarable7Seg_16x32,
     16,
     16,
     32,
     32,

+ 2 - 2
components/display/tarablessd13x6/fonts/font_tarable7seg_32x64.c → components/display/fonts/font_tarable7seg_32x64.c

@@ -1,4 +1,4 @@
-#include <ssd13x6_font.h>
+#include <gds_font.h>
 
 
 //WARNING: This Font Require X-GLCD Lib.
 //WARNING: This Font Require X-GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
 //         You can not use it with MikroE GLCD Lib.
@@ -109,7 +109,7 @@ static const uint8_t Tarable7Seg_32x64[ ] = {
     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char 
     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Code for char 
 };
 };
 
 
-const struct SSD13x6_FontDef Font_Tarable7Seg_32x64 = {
+const struct GDS_FontDef Font_Tarable7Seg_32x64 = {
     Tarable7Seg_32x64,
     Tarable7Seg_32x64,
     32,
     32,
     64,
     64,

+ 0 - 123
components/display/tarablessd13x6/ifaces/default_if_spi.c

@@ -1,123 +0,0 @@
-
-/**
- * Copyright (c) 2017-2018 Tara Keeling
- * 
- * This software is released under the MIT License.
- * https://opensource.org/licenses/MIT
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <driver/spi_master.h>
-#include <driver/gpio.h>
-#include <freertos/task.h>
-#include "ssd13x6.h"
-#include "ssd13x6_default_if.h"
-
-static const int SSD13x6_SPI_Command_Mode = 0;
-static const int SSD13x6_SPI_Data_Mode = 1;
-
-static spi_host_device_t SPIHost;
-static int DCPin;
-
-static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength );
-static bool SPIDefaultWriteCommand( struct SSD13x6_Device* DeviceHandle, SSDCmd Command );
-static bool SPIDefaultWriteData( struct SSD13x6_Device* DeviceHandle, const uint8_t* Data, size_t DataLength );
-static bool SPIDefaultReset( struct SSD13x6_Device* DeviceHandle );
-
-bool SSD13x6_SPIMasterInitDefault( int SPI, int DC ) {
-	SPIHost = SPI;
-	DCPin = DC;
-    return true;
-}
-
-bool SSD13x6_SPIMasterAttachDisplayDefault( struct SSD13x6_Device* DeviceHandle, int Model, int Width, int Height, int CSPin, int RSTPin, int Speed ) {
-    spi_device_interface_config_t SPIDeviceConfig;
-    spi_device_handle_t SPIDeviceHandle;
-
-    NullCheck( DeviceHandle, return false );
-	
-	if (CSPin >= 0) {
-		ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( CSPin, GPIO_MODE_OUTPUT ), return false );
-		ESP_ERROR_CHECK_NONFATAL( gpio_set_level( CSPin, 0 ), return false );
-	}	
-
-    memset( &SPIDeviceConfig, 0, sizeof( spi_device_interface_config_t ) );
-
-    SPIDeviceConfig.clock_speed_hz = Speed > 0 ? Speed : SPI_MASTER_FREQ_8M;
-    SPIDeviceConfig.spics_io_num = CSPin;
-    SPIDeviceConfig.queue_size = 1;
-
-    if ( RSTPin >= 0 ) {
-        ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
-        ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 0 ), return false );
-    }
-
-    ESP_ERROR_CHECK_NONFATAL( spi_bus_add_device( SPIHost, &SPIDeviceConfig, &SPIDeviceHandle ), return false );
-
-	memset( DeviceHandle, 0, sizeof( struct SSD13x6_Device ) );	
-	DeviceHandle->Model = Model;
-		
-    return SSD13x6_Init_SPI( DeviceHandle,
-        Width,
-        Height,
-        RSTPin,
-        CSPin,
-        SPIDeviceHandle,
-        SPIDefaultWriteCommand,
-        SPIDefaultWriteData,
-        SPIDefaultReset
-    );
-}
-
-static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength ) {
-    spi_transaction_t SPITransaction = { 0 };
-
-    NullCheck( SPIHandle, return false );
-    NullCheck( Data, return false );
-
-    if ( DataLength > 0 ) {
-		gpio_set_level( DCPin, WriteMode );
-		
-		SPITransaction.length = DataLength * 8;
-		SPITransaction.tx_buffer = Data;
-            
-		// only do polling as we don't have contention on SPI (otherwise DMA for transfers > 16 bytes)		
-		ESP_ERROR_CHECK_NONFATAL( spi_device_polling_transmit(SPIHandle, &SPITransaction), return false );
-    }
-
-    return true;
-}
-
-static bool SPIDefaultWriteCommand( struct SSD13x6_Device* DeviceHandle, SSDCmd Command ) {
-    static uint8_t CommandByte = 0;
-
-    NullCheck( DeviceHandle, return false );
-    NullCheck( DeviceHandle->SPIHandle, return false );
-
-    CommandByte = Command;
-
-    return SPIDefaultWriteBytes( DeviceHandle->SPIHandle, SSD13x6_SPI_Command_Mode, &CommandByte, 1 );
-}
-
-static bool SPIDefaultWriteData( struct SSD13x6_Device* DeviceHandle, const uint8_t* Data, size_t DataLength ) {
-    NullCheck( DeviceHandle, return false );
-    NullCheck( DeviceHandle->SPIHandle, return false );
-
-    return SPIDefaultWriteBytes( DeviceHandle->SPIHandle, SSD13x6_SPI_Data_Mode, Data, DataLength );
-}
-
-static bool SPIDefaultReset( struct SSD13x6_Device* DeviceHandle ) {
-    NullCheck( DeviceHandle, return false );
-
-    if ( DeviceHandle->RSTPin >= 0 ) {
-        ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DeviceHandle->RSTPin, 0 ), return false );
-            vTaskDelay( pdMS_TO_TICKS( 100 ) );
-        ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DeviceHandle->RSTPin, 1 ), return false );
-    }
-
-    return true;
-}
-

+ 0 - 351
components/display/tarablessd13x6/ssd13x6.c

@@ -1,351 +0,0 @@
-/**
- * Copyright (c) 2017-2018 Tara Keeling
- * 
- * This software is released under the MIT License.
- * https://opensource.org/licenses/MIT
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <math.h>
-#include <esp_heap_caps.h>
-
-#include "ssd13x6.h"
-
-#define SHADOW_BUFFER
-
-// used by both but different
-static uint8_t SSDCmd_Set_Display_Start_Line;
-static uint8_t SSDCmd_Set_Display_Offset;
-static uint8_t SSDCmd_Set_Column_Address;
-static uint8_t SSDCmd_Set_Display_CLK;
-static uint8_t SSDCmd_Set_Page_Address;
-
-// misc boundaries
-static uint8_t SSD13x6_Max_Col;
-static const uint8_t SSD13x6_Max_Row = 7;
-
-static bool SSD13x6_Init( struct SSD13x6_Device* DeviceHandle, int Width, int Height );
-
-int  SSD13x6_GetCaps( struct SSD13x6_Device* DeviceHandle ) {
-	if (DeviceHandle->Model == SH1106) return 0;
-	else return CAPS_COLUMN_RANGE | CAPS_PAGE_RANGE	| CAPS_ADDRESS_VERTICAL;
-}
-
-bool SSD13x6_WriteCommand( struct SSD13x6_Device* DeviceHandle, SSDCmd SSDCommand ) {
-    NullCheck( DeviceHandle->WriteCommand, return false );
-    return ( DeviceHandle->WriteCommand ) ( DeviceHandle, SSDCommand );
-}
-
-bool SSD13x6_WriteData( struct SSD13x6_Device* DeviceHandle, uint8_t* Data, size_t DataLength ) {
-    NullCheck( DeviceHandle->WriteData, return false );
-    return ( DeviceHandle->WriteData ) ( DeviceHandle, Data, DataLength );
-}
-
-void SSD13x6_SetMuxRatio( struct SSD13x6_Device* DeviceHandle, uint8_t Ratio ) {
-    SSD13x6_WriteCommand( DeviceHandle, 0xA8 );
-    SSD13x6_WriteCommand( DeviceHandle, Ratio );
-}
-
-void SSD13x6_SetDisplayOffset( struct SSD13x6_Device* DeviceHandle, uint8_t Offset ) {
-    SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Display_Offset );
-    SSD13x6_WriteCommand( DeviceHandle, Offset );
-}
-
-void SSD13x6_SetDisplayStartLine( struct SSD13x6_Device* DeviceHandle, int Line ) {
-    SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Display_Start_Line + ( uint32_t ) ( Line & 0x1F ) );
-}
-
-void SSD13x6_SetContrast( struct SSD13x6_Device* DeviceHandle, uint8_t Contrast ) {
-    SSD13x6_WriteCommand( DeviceHandle, 0x81 );
-    SSD13x6_WriteCommand( DeviceHandle, Contrast );
-}
-
-void SSD13x6_EnableDisplayRAM( struct SSD13x6_Device* DeviceHandle ) {
-    SSD13x6_WriteCommand( DeviceHandle, 0xA4 );
-}
-
-void SSD13x6_DisableDisplayRAM( struct SSD13x6_Device* DeviceHandle ) {
-    SSD13x6_WriteCommand( DeviceHandle, 0xA5 );
-}
-
-void SSD13x6_SetInverted( struct SSD13x6_Device* DeviceHandle, bool Inverted ) {
-    SSD13x6_WriteCommand( DeviceHandle, Inverted ? 0xA7 : 0xA6 );
-}
-
-void SSD13x6_SetDisplayClocks( struct SSD13x6_Device* DeviceHandle, uint32_t DisplayClockDivider, uint32_t OSCFrequency ) {
-    DisplayClockDivider&= 0x0F;
-    OSCFrequency&= 0x0F;
-    SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Display_CLK );
-    SSD13x6_WriteCommand( DeviceHandle, ( ( OSCFrequency << 4 ) | DisplayClockDivider ) );
-}
-
-void SSD13x6_DisplayOn( struct SSD13x6_Device* DeviceHandle ) {
-    SSD13x6_WriteCommand( DeviceHandle, 0xAF );
-}
-
-void SSD13x6_DisplayOff( struct SSD13x6_Device* DeviceHandle ) {
-    SSD13x6_WriteCommand( DeviceHandle, 0xAE );
-}
-
-void SSD132x_ReMap( struct SSD13x6_Device* DeviceHandle ) {
-	SSD13x6_WriteCommand( DeviceHandle, 0xA0 );
-	SSD13x6_WriteCommand( DeviceHandle, DeviceHandle->ReMap );
-}
-
-void SSD13x6_SetDisplayAddressMode( struct SSD13x6_Device* DeviceHandle, SSD13x6_AddressMode AddressMode ) {
-	switch (DeviceHandle->Model) {
-	case SH1106:
-		// does not exist on SH1106
-		break;
-	case SSD1306:
-		SSD13x6_WriteCommand( DeviceHandle, 0x20 );
-		SSD13x6_WriteCommand( DeviceHandle, AddressMode );
-		break;
-	case SSD1326:
-		DeviceHandle->ReMap = (AddressMode == AddressMode_Horizontal) ? (DeviceHandle->ReMap & ~0x80) : (DeviceHandle->ReMap | 0x80);
-		SSD132x_ReMap(DeviceHandle);
-		break;
-	}
-}
-
-void SSD13x6_Update( struct SSD13x6_Device* DeviceHandle ) {
-#ifdef SHADOW_BUFFER
-	// not sure the compiler does not have to redo all calculation in for loops, so local it is
-	int width = DeviceHandle->Width, rows = DeviceHandle->Height / 8;
-	uint8_t *optr = DeviceHandle->Shadowbuffer, *iptr = DeviceHandle->Framebuffer;
-	
-	// by row, find first and last columns that have been updated
-	for (int r = 0; r < rows; r++) {
-		uint8_t first = 0, last;	
-		for (int c = 0; c < width; c++) {
-			if (*iptr != *optr) {
-				if (!first) first = c + 1;
-				last = c ;
-			}	
-			*optr++ = *iptr++;
-		}
-		
-		// now update the display by "byte rows"
-		if (first--) {
-			SSD13x6_SetColumnAddress( DeviceHandle, first, last );
-			SSD13x6_SetPageAddress( DeviceHandle, r, r);
-			SSD13x6_WriteData( DeviceHandle, DeviceHandle->Shadowbuffer + r*width + first, last - first + 1);
-		}
-	}	
-#else	
-	if (DeviceHandle->Model == SH1106) {
-		// SH1106 requires a page-by-page update and has no end Page/Column
-		for (int i = 0; i < DeviceHandle->Height / 8 ; i++) {
-			SSD13x6_SetPageAddress( DeviceHandle, i, 0);
-			SSD13x6_SetColumnAddress( DeviceHandle, 0, 0);			
-			SSD13x6_WriteData( DeviceHandle, DeviceHandle->Framebuffer + i*DeviceHandle->Width, DeviceHandle->Width );
-		}	
-	} else {	
-		// others have an automatic counter and end Page/Column
-		SSD13x6_SetColumnAddress( DeviceHandle, 0, DeviceHandle->Width - 1);
-		SSD13x6_SetPageAddress( DeviceHandle, 0, DeviceHandle->Height / 8 - 1);
-		SSD13x6_WriteData( DeviceHandle, DeviceHandle->Framebuffer, DeviceHandle->FramebufferSize );
-	}	
-#endif	
-}
-
-void SSD13x6_WriteRawData( struct SSD13x6_Device* DeviceHandle, uint8_t* Data, size_t DataLength ) {
-    NullCheck( Data, return );
-    DataLength = DataLength > DeviceHandle->FramebufferSize ? DeviceHandle->FramebufferSize : DataLength;
-    if ( DataLength > 0 ) SSD13x6_WriteData( DeviceHandle, Data, DataLength );
-}
-
-void SSD13x6_SetHFlip( struct SSD13x6_Device* DeviceHandle, bool On ) {
-	switch (DeviceHandle->Model) {
-	case SH1106:		
-	case SSD1306:	
-		SSD13x6_WriteCommand( DeviceHandle, On ? 0xA1 : 0xA0 );
-		break;
-	case SSD1326:
-		DeviceHandle->ReMap = On ? (DeviceHandle->ReMap | 0x01) : (DeviceHandle->ReMap & ~0x01);
-		SSD132x_ReMap(DeviceHandle);
-		break;
-	}	
-}
-
-void SSD13x6_SetVFlip( struct SSD13x6_Device* DeviceHandle, bool On ) {
-	switch (DeviceHandle->Model) {
-	case SH1106:	
-	case SSD1306:	
-		SSD13x6_WriteCommand( DeviceHandle, On ? 0xC8 : 0xC0 );
-		break;
-	case SSD1326:
-		DeviceHandle->ReMap = On ? (DeviceHandle->ReMap | 0x05) : (DeviceHandle->ReMap & ~0x05);
-		SSD132x_ReMap( DeviceHandle );
-		break;
-	}	
-}
-
-void SSD13x6_SetColumnAddress( struct SSD13x6_Device* DeviceHandle, uint8_t Start, uint8_t End ) {
-    CheckBounds( Start > SSD13x6_Max_Col, return );
-    CheckBounds( End > SSD13x6_Max_Col, return );
-	
-	// on SH1106, there is no "end column"
-	if (DeviceHandle->Model == SH1106) {
-		// well, unfortunately this driver is 132 colums but most displays are 128...
-		if (DeviceHandle->Width != 132) Start += 2;
-		SSD13x6_WriteCommand( DeviceHandle, 0x10 | (Start >> 4) );
-		SSD13x6_WriteCommand( DeviceHandle, 0x00 | (Start & 0x0f) );
-	} else {	
-		SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Column_Address );
-		SSD13x6_WriteCommand( DeviceHandle, Start );
-		SSD13x6_WriteCommand( DeviceHandle, End );
-	}	
-}
-
-void SSD13x6_SetPageAddress( struct SSD13x6_Device* DeviceHandle, uint8_t Start, uint8_t End ) {
-    NullCheck( DeviceHandle, return );
-
-    CheckBounds( Start > SSD13x6_Max_Row, return );
-    CheckBounds( End > SSD13x6_Max_Row, return );
-	
-	// on SH1106, there is no "end page"
-	if (DeviceHandle->Model == SH1106) {
-			SSD13x6_WriteCommand( DeviceHandle, 0xB0 | Start );			
-	} else {	
-		// in case of SSD1326, this is sub-optimal as it can address by line, not by page
-		if (DeviceHandle->Model != SSD1306) {
-			Start *= 8;
-			End = (End + 1) * 8 - 1;
-		}
-	
-		SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Page_Address );	
-		SSD13x6_WriteCommand( DeviceHandle, Start );
-		SSD13x6_WriteCommand( DeviceHandle, End );
-	}	
-}
-
-bool SSD13x6_HWReset( struct SSD13x6_Device* DeviceHandle ) {
-    NullCheck( DeviceHandle, return 0 );
-
-    if ( DeviceHandle->Reset != NULL ) {
-        return ( DeviceHandle->Reset ) ( DeviceHandle );
-    }
-
-    /* This should always return true if there is no reset callback as
-     * no error would have occurred during the non existant reset.
-     */
-    return true;
-}
-
-static bool SSD13x6_Init( struct SSD13x6_Device* DeviceHandle, int Width, int Height ) {
-    DeviceHandle->Width = Width;
-    DeviceHandle->Height = Height;
-	
-#ifdef SHADOW_BUFFER
-	DeviceHandle->Shadowbuffer = heap_caps_malloc( DeviceHandle->FramebufferSize, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA );
-	memset( DeviceHandle->Shadowbuffer, 0xFF, DeviceHandle->FramebufferSize );
-#endif	
-	
-	SSD13x6_HWReset( DeviceHandle );
-	SSD13x6_DisplayOff( DeviceHandle );
-
-	if (DeviceHandle->Model == SSD1306 || DeviceHandle->Model == SH1106) {
-		SSDCmd_Set_Display_Start_Line = 0x40;
-		SSDCmd_Set_Display_Offset = 0xD3;
-		SSDCmd_Set_Column_Address = 0x21,
-		SSDCmd_Set_Display_CLK = 0xD5;
-		SSDCmd_Set_Page_Address = 0x22;		
-		SSD13x6_Max_Col = 127;
-		
-		if (DeviceHandle->Model == SSD1306) {
-			// charge pump regulator, do direct init
-			SSD13x6_WriteCommand( DeviceHandle, 0x8D );
-			SSD13x6_WriteCommand( DeviceHandle, 0x14 ); 
-			
-			// COM pins HW config (alternative:EN if 64, DIS if 32, remap:DIS) - some display might need something difference
-			SSD13x6_WriteCommand( DeviceHandle, 0xDA );
-			SSD13x6_WriteCommand( DeviceHandle, ((Height == 64 ? 1 : 0) << 4) | (0 < 5) );
-
-		} else {
-			// charge pump regulator, do direct init
-			SSD13x6_WriteCommand( DeviceHandle, 0xAD );
-			SSD13x6_WriteCommand( DeviceHandle, 0x8B ); 
-			
-			// COM pins HW config (alternative:EN) - some display might need something difference
-			SSD13x6_WriteCommand( DeviceHandle, 0xDA );
-			SSD13x6_WriteCommand( DeviceHandle, 1 << 4);
-		}
-
-	} else if (DeviceHandle->Model == SSD1326) {
-		SSDCmd_Set_Display_Start_Line = 0xA1;
-		SSDCmd_Set_Display_Offset = 0xA2;
-		SSDCmd_Set_Column_Address = 0x15;
-		SSDCmd_Set_Display_CLK = 0xB3;
-		SSDCmd_Set_Page_Address = 0x75;		// not really a page but a row
-		
-		SSD13x6_Max_Col = 255;
-		
-		// no gray scale
-		DeviceHandle->ReMap |= 0x10;
-		SSD132x_ReMap( DeviceHandle );
-	}
-
-	SSD13x6_SetMuxRatio( DeviceHandle, Height - 1 );
-    SSD13x6_SetDisplayOffset( DeviceHandle, 0x00 );
-	SSD13x6_SetDisplayStartLine( DeviceHandle, 0 );
-	SSD13x6_SetContrast( DeviceHandle, 0x7F );
-    SSD13x6_DisableDisplayRAM( DeviceHandle );
-	SSD13x6_SetVFlip( DeviceHandle, false );
-	SSD13x6_SetHFlip( DeviceHandle, false );
-	SSD13x6_SetInverted( DeviceHandle, false );
-    SSD13x6_SetDisplayClocks( DeviceHandle, 0, 8 );
-	SSD13x6_SetDisplayAddressMode( DeviceHandle, AddressMode_Horizontal );
-    SSD13x6_SetColumnAddress( DeviceHandle, 0, DeviceHandle->Width - 1 );
-    SSD13x6_SetPageAddress( DeviceHandle, 0, ( DeviceHandle->Height / 8 ) - 1 );
-	SSD13x6_EnableDisplayRAM( DeviceHandle );
-    SSD13x6_DisplayOn( DeviceHandle );
-	SSD13x6_Update( DeviceHandle );
-
-    return true;
-}
-
-bool SSD13x6_Init_I2C( struct SSD13x6_Device* DeviceHandle, int Width, int Height, int I2CAddress, int ResetPin, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset ) {
-    NullCheck( DeviceHandle, return false );
-    NullCheck( WriteCommand, return false );
-    NullCheck( WriteData, return false );
-
-    DeviceHandle->WriteCommand = WriteCommand;
-    DeviceHandle->WriteData = WriteData;
-    DeviceHandle->Reset = Reset;
-    DeviceHandle->Address = I2CAddress;
-    DeviceHandle->RSTPin = ResetPin;
-	
-	DeviceHandle->FramebufferSize = ( Width * Height ) / 8;
-	DeviceHandle->Framebuffer = calloc( 1, DeviceHandle->FramebufferSize );
-    NullCheck( DeviceHandle->Framebuffer, return false );
-    
-    return SSD13x6_Init( DeviceHandle, Width, Height );
-}
-
-bool SSD13x6_Init_SPI( struct SSD13x6_Device* DeviceHandle, int Width, int Height, int ResetPin, int CSPin, spi_device_handle_t SPIHandle, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset ) {
-    NullCheck( DeviceHandle, return false );
-    NullCheck( WriteCommand, return false );
-    NullCheck( WriteData, return false );
-
-    DeviceHandle->WriteCommand = WriteCommand;
-    DeviceHandle->WriteData = WriteData;
-    DeviceHandle->Reset = Reset;
-    DeviceHandle->SPIHandle = SPIHandle;
-    DeviceHandle->RSTPin = ResetPin;
-    DeviceHandle->CSPin = CSPin;
-	
-	DeviceHandle->FramebufferSize = ( Width * Height ) / 8;
-#ifdef SHADOW_BUFFER	
-	DeviceHandle->Framebuffer = calloc( 1, DeviceHandle->FramebufferSize );
-#else	
-    DeviceHandle->Framebuffer = heap_caps_calloc( 1, DeviceHandle->FramebufferSize, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA );
-#endif
-    NullCheck( DeviceHandle->Framebuffer, return false );
-	
-    return SSD13x6_Init( DeviceHandle, Width, Height );
-}

+ 0 - 99
components/display/tarablessd13x6/ssd13x6.h

@@ -1,99 +0,0 @@
-#ifndef _SSD13X6_H_
-#define _SSD13X6_H_
-
-/* For uint(X)_t */
-#include <stdint.h>
-
-/* For booooool */
-#include <stdbool.h>
-
-#include "sdkconfig.h"
-#include "ssd13x6_err.h"
-
-#define SSD_ALWAYS_INLINE __attribute__( ( always_inline ) )
-
-#define CAPS_COLUMN_RANGE		0x01
-#define CAPS_PAGE_RANGE			0x02
-#define CAPS_ADDRESS_VERTICAL	0x04
-
-#if ! defined BIT
-#define BIT( n ) ( 1 << n )
-#endif
-
-typedef uint8_t SSDCmd;
-
-typedef enum {
-    AddressMode_Horizontal = 0,
-    AddressMode_Vertical,
-    AddressMode_Page,
-    AddressMode_Invalid
-} SSD13x6_AddressMode;
-
-struct SSD13x6_Device;
-
-/*
- * These can optionally return a succeed/fail but are as of yet unused in the driver.
- */
-typedef bool ( *WriteCommandProc ) ( struct SSD13x6_Device* DeviceHandle, SSDCmd Command );
-typedef bool ( *WriteDataProc ) ( struct SSD13x6_Device* DeviceHandle, const uint8_t* Data, size_t DataLength );
-typedef bool ( *ResetProc ) ( struct SSD13x6_Device* DeviceHandle );
-
-struct spi_device_t;
-typedef struct spi_device_t* spi_device_handle_t;
-
-struct SSD13x6_FontDef;
-
-struct SSD13x6_Device {
-    /* I2C Specific */
-    int Address;
-
-    /* SPI Specific */
-    spi_device_handle_t SPIHandle;
-    int RSTPin;
-    int CSPin;
-
-    /* Everything else */
-    int Width;
-    int Height;
-
-	enum { SSD1306, SSD1326, SH1106 } Model;
-	uint8_t ReMap;
-    uint8_t* Framebuffer, *Shadowbuffer;
-    int FramebufferSize;
-
-    WriteCommandProc WriteCommand;
-    WriteDataProc WriteData;
-    ResetProc Reset;
-
-    const struct SSD13x6_FontDef* Font;
-    bool FontForceProportional;
-    bool FontForceMonospace;
-};
-
-void SSD13x6_SetMuxRatio( struct SSD13x6_Device* DeviceHandle, uint8_t Ratio );
-void SSD13x6_SetDisplayOffset( struct SSD13x6_Device* DeviceHandle, uint8_t Offset );
-void SSD13x6_SetDisplayStartLines( struct SSD13x6_Device* DeviceHandle );
-
-void SSD13x6_SetSegmentRemap( struct SSD13x6_Device* DeviceHandle, bool Remap );
-
-void SSD13x6_SetContrast( struct SSD13x6_Device* DeviceHandle, uint8_t Contrast );
-void SSD13x6_EnableDisplayRAM( struct SSD13x6_Device* DeviceHandle );
-void SSD13x6_DisableDisplayRAM( struct SSD13x6_Device* DeviceHandle );
-void SSD13x6_SetInverted( struct SSD13x6_Device* DeviceHandle, bool Inverted );
-void SSD13x6_SetHFlip( struct SSD13x6_Device* DeviceHandle, bool On );
-void SSD13x6_SetVFlip( struct SSD13x6_Device* DeviceHandle, bool On );
-void SSD13x6_DisplayOn( struct SSD13x6_Device* DeviceHandle );
-void SSD13x6_DisplayOff( struct SSD13x6_Device* DeviceHandle ); 
-void SSD13x6_SetDisplayAddressMode( struct SSD13x6_Device* DeviceHandle, SSD13x6_AddressMode AddressMode );
-void SSD13x6_Update( struct SSD13x6_Device* DeviceHandle );
-void SSD13x6_SetDisplayClocks( struct SSD13x6_Device* DeviceHandle, uint32_t DisplayClockDivider, uint32_t OSCFrequency );
-void SSD13x6_SetColumnAddress( struct SSD13x6_Device* DeviceHandle, uint8_t Start, uint8_t End );
-void SSD13x6_SetPageAddress( struct SSD13x6_Device* DeviceHandle, uint8_t Start, uint8_t End );
-bool SSD13x6_HWReset( struct SSD13x6_Device* DeviceHandle );
-bool SSD13x6_Init_I2C( struct SSD13x6_Device* DeviceHandle, int Width, int Height, int I2CAddress, int ResetPin, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset );
-bool SSD13x6_Init_SPI( struct SSD13x6_Device* DeviceHandle, int Width, int Height, int ResetPin, int CSPin, spi_device_handle_t SPIHandle, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset );
-int  SSD13x6_GetCaps( struct SSD13x6_Device* DeviceHandle );
-
-void SSD13x6_WriteRawData( struct SSD13x6_Device* DeviceHandle, uint8_t* Data, size_t DataLength );
-
-#endif

+ 0 - 18
components/display/tarablessd13x6/ssd13x6_default_if.h

@@ -1,18 +0,0 @@
-#ifndef _SSD13x6_DEFAULT_IF_H_
-#define _SSD13x6_DEFAULT_IF_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool SSD13x6_I2CMasterInitDefault( int PortNumber, int SDA, int SCL );
-bool SSD13x6_I2CMasterAttachDisplayDefault( struct SSD13x6_Device* DisplayHandle, int Model, int Width, int Height, int I2CAddress, int RSTPin );
-
-bool SSD13x6_SPIMasterInitDefault( int SPI, int DC);
-bool SSD13x6_SPIMasterAttachDisplayDefault( struct SSD13x6_Device* DeviceHandle, int Model, int Width, int Height, int CSPin, int RSTPin, int Speed );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 253
components/display/tarablessd13x6/ssd13x6_draw.c

@@ -1,253 +0,0 @@
-/**
- * Copyright (c) 2017-2018 Tara Keeling
- * 
- * This software is released under the MIT License.
- * https://opensource.org/licenses/MIT
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <math.h>
-#include <esp_attr.h>
-
-#include "ssd13x6.h"
-#include "ssd13x6_draw.h"
-
-#undef NullCheck
-#define NullCheck(X,Y)
-
-__attribute__( ( always_inline ) ) static inline bool IsPixelVisible( struct SSD13x6_Device* DeviceHandle, int x, int y )  {
-    bool Result = (
-        ( x >= 0 ) &&
-        ( x < DeviceHandle->Width ) &&
-        ( y >= 0 ) &&
-        ( y < DeviceHandle->Height )
-    ) ? true : false;
-
-#if CONFIG_SSD13x6_CLIPDEBUG > 0
-    if ( Result == false ) {
-        ClipDebug( x, y );
-    }
-#endif
-
-    return Result;
-}
-
-__attribute__( ( always_inline ) ) static inline void SwapInt( int* a, int* b ) {
-    int Temp = *b;
-
-    *b = *a;
-    *a = Temp;
-}
-
-inline void IRAM_ATTR SSD13x6_DrawPixelFast( struct SSD13x6_Device* DeviceHandle, int X, int Y, int Color ) {
-    uint32_t YBit = ( Y & 0x07 );
-    uint8_t* FBOffset = NULL;
-
-    /* 
-     * We only need to modify the Y coordinate since the pitch
-     * of the screen is the same as the width.
-     * Dividing Y by 8 gives us which row the pixel is in but not
-     * the bit position.
-     */
-    Y>>= 3;
-
-    FBOffset = DeviceHandle->Framebuffer + ( ( Y * DeviceHandle->Width ) + X );
-
-    if ( Color == SSD_COLOR_XOR ) {
-        *FBOffset ^= BIT( YBit );
-    } else {
-        *FBOffset = ( Color == SSD_COLOR_WHITE ) ? *FBOffset | BIT( YBit ) : *FBOffset & ~BIT( YBit );
-    }
-}
-
-void IRAM_ATTR SSD13x6_DrawPixel( struct SSD13x6_Device* DeviceHandle, int x, int y, int Color ) {
-    NullCheck( DeviceHandle, return );
-
-    if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
-        SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color );
-    }
-}
-
-void IRAM_ATTR SSD13x6_DrawHLine( struct SSD13x6_Device* DeviceHandle, int x, int y, int Width, int Color ) {
-    int XEnd = x + Width;
-
-    NullCheck( DeviceHandle, return );
-    NullCheck( DeviceHandle->Framebuffer, return );
-
-    for ( ; x < XEnd; x++ ) {
-        if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
-            SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color );
-        } else {
-            break;
-        }
-    }
-}
-
-void IRAM_ATTR SSD13x6_DrawVLine( struct SSD13x6_Device* DeviceHandle, int x, int y, int Height, int Color ) {
-    int YEnd = y + Height;
-
-    NullCheck( DeviceHandle, return );
-    NullCheck( DeviceHandle->Framebuffer, return );
-
-    for ( ; y < YEnd; y++ ) {
-        if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
-            SSD13x6_DrawPixel( DeviceHandle, x, y, Color );
-        } else {
-            break;
-        }
-    }
-}
-
-static inline void IRAM_ATTR DrawWideLine( struct SSD13x6_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
-    int dx = ( x1 - x0 );
-    int dy = ( y1 - y0 );
-    int Error = 0;
-    int Incr = 1;
-    int x = x0;
-    int y = y0;
-
-    if ( dy < 0 ) {
-        Incr = -1;
-        dy = -dy;
-    }
-
-    Error = ( dy * 2 ) - dx;
-
-    for ( ; x < x1; x++ ) {
-        if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
-            SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color );
-        }
-
-        if ( Error > 0 ) {
-            Error-= ( dx * 2 );
-            y+= Incr;
-        }
-
-        Error+= ( dy * 2 );
-    }
-}
-
-static inline void IRAM_ATTR DrawTallLine( struct SSD13x6_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
-    int dx = ( x1 - x0 );
-    int dy = ( y1 - y0 );
-    int Error = 0;
-    int Incr = 1;
-    int x = x0;
-    int y = y0;
-
-    if ( dx < 0 ) {
-        Incr = -1;
-        dx = -dx;
-    }
-
-    Error = ( dx * 2 ) - dy;
-
-    for ( ; y < y1; y++ ) {
-        if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
-            SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color );
-        }
-
-        if ( Error > 0 ) {
-            Error-= ( dy * 2 );
-            x+= Incr;
-        }
-
-        Error+= ( dx * 2 );
-    }
-}
-
-void IRAM_ATTR SSD13x6_DrawLine( struct SSD13x6_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
-    NullCheck( DeviceHandle, return );
-    NullCheck( DeviceHandle->Framebuffer, return );
-
-    if ( x0 == x1 ) {
-        SSD13x6_DrawVLine( DeviceHandle, x0, y0, ( y1 - y0 ), Color );
-    } else if ( y0 == y1 ) {
-        SSD13x6_DrawHLine( DeviceHandle, x0, y0, ( x1 - x0 ), Color );
-    } else {
-        if ( abs( x1 - x0 ) > abs( y1 - y0 ) ) {
-            /* Wide ( run > rise ) */
-            if ( x0 > x1 ) {
-                SwapInt( &x0, &x1 );
-                SwapInt( &y0, &y1 );
-            }
-
-            DrawWideLine( DeviceHandle, x0, y0, x1, y1, Color );
-        } else {
-            /* Tall ( rise > run ) */
-            if ( y0 > y1 ) {
-                SwapInt( &y0, &y1 );
-                SwapInt( &x0, &x1 );
-            }
-
-            DrawTallLine( DeviceHandle, x0, y0, x1, y1, Color );
-        }
-    }
-}
-
-void IRAM_ATTR SSD13x6_DrawBox( struct SSD13x6_Device* DeviceHandle, int x1, int y1, int x2, int y2, int Color, bool Fill ) {
-    int Width = ( x2 - x1 );
-    int Height = ( y2 - y1 );
-
-    NullCheck( DeviceHandle, return );
-    NullCheck( DeviceHandle->Framebuffer, return );
-
-    if ( Fill == false ) {
-        /* Top side */
-        SSD13x6_DrawHLine( DeviceHandle, x1, y1, Width, Color );
-
-        /* Bottom side */
-        SSD13x6_DrawHLine( DeviceHandle, x1, y1 + Height, Width, Color );
-
-        /* Left side */
-        SSD13x6_DrawVLine( DeviceHandle, x1, y1, Height, Color );
-
-        /* Right side */
-        SSD13x6_DrawVLine( DeviceHandle, x1 + Width, y1, Height, Color );
-    } else {
-        /* Fill the box by drawing horizontal lines */
-        for ( ; y1 <= y2; y1++ ) {
-            SSD13x6_DrawHLine( DeviceHandle, x1, y1, Width, Color );
-        }
-    }
-}
-
-void SSD13x6_Clear( struct SSD13x6_Device* DeviceHandle, int Color ) {
-    NullCheck( DeviceHandle, return );
-    NullCheck( DeviceHandle->Framebuffer, return );
-
-    memset( DeviceHandle->Framebuffer, Color, DeviceHandle->FramebufferSize );
-}
-
-void SSD13x6_ClearWindow( struct SSD13x6_Device* DeviceHandle, int x1, int y1, int x2, int y2, int Color ) {
-    NullCheck( DeviceHandle, return );
-    NullCheck( DeviceHandle->Framebuffer, return );
-	
-/*	
-	int xr = ((x1 - 1) / 8) + 1 ) * 8;
-	int xl = (x2 / 8) * 8;
-	
-	for (int y = y1; y <= y2; y++) {
-		for (int x = x1; x < xr; x++) SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color);
-		if (xl > xr) memset( DeviceHandle->Framebuffer + (y / 8) * DeviceHandle->Width + xr, 0, xl - xr );
-		for (int x = xl; x <= x2; x++) SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color);
-	}
-	
-	return;
-*/	
-		
-	// cheap optimization on boundaries
-	if (x1 == 0 && x2 == DeviceHandle->Width - 1 && y1 % 8 == 0 && (y2 + 1) % 8 == 0) {
-		memset( DeviceHandle->Framebuffer + (y1 / 8) * DeviceHandle->Width, 0, (y2 - y1 + 1) / 8 * DeviceHandle->Width );
-	} else {
-		for (int y = y1; y <= y2; y++) {
-			for (int x = x1; x <= x2; x++) {
-				SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color);
-			}		
-		}	
-	}	
-}

+ 0 - 54
components/display/tarablessd13x6/ssd13x6_draw.h

@@ -1,54 +0,0 @@
-#ifndef _SSD13x6_DRAW_H_
-#define _SSD13x6_DRAW_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "sdkconfig.h"
-
-#define SSD13x6_CLIPDEBUG_NONE 0
-#define SSD13x6_CLIPDEBUG_WARNING 1
-#define SSD13x6_CLIPDEBUG_ERROR 2
-
-#if CONFIG_SSD13x6_CLIPDEBUG == SSD13x6_CLIPDEBUG_NONE
-    /*
-     * Clip silently with no console output.
-     */
-    #define ClipDebug( x, y )
-#elif CONFIG_SSD13x6_CLIPDEBUG == SSD13x6_CLIPDEBUG_WARNING
-    /*
-     * Log clipping to the console as a warning.
-     */
-    #define ClipDebug( x, y ) { \
-        ESP_LOGW( __FUNCTION__, "Line %d: Pixel at %d, %d CLIPPED", __LINE__, x, y ); \
-    }
-#elif CONFIG_SSD13x6_CLIPDEBUG == SSD13x6_CLIPDEBUG_ERROR
-    /*
-     * Log clipping as an error to the console.
-     * Also invokes an abort with stack trace.
-     */
-    #define ClipDebug( x, y ) { \
-        ESP_LOGE( __FUNCTION__, "Line %d: Pixel at %d, %d CLIPPED, ABORT", __LINE__, x, y ); \
-        abort( ); \
-    }
-#endif
-
-#define SSD_COLOR_BLACK 0
-#define SSD_COLOR_WHITE 1
-#define SSD_COLOR_XOR 2
-
-void SSD13x6_Clear( struct SSD13x6_Device* DeviceHandle, int Color );
-void SSD13x6_ClearWindow( struct SSD13x6_Device* DeviceHandle, int x1, int y1, int x2, int y2, int Color );
-void SSD13x6_DrawPixel( struct SSD13x6_Device* DeviceHandle, int X, int Y, int Color );
-void SSD13x6_DrawPixelFast( struct SSD13x6_Device* DeviceHandle, int X, int Y, int Color );
-void SSD13x6_DrawHLine( struct SSD13x6_Device* DeviceHandle, int x, int y, int Width, int Color );
-void SSD13x6_DrawVLine( struct SSD13x6_Device* DeviceHandle, int x, int y, int Height, int Color );
-void SSD13x6_DrawLine( struct SSD13x6_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color );
-void SSD13x6_DrawBox( struct SSD13x6_Device* DeviceHandle, int x1, int y1, int x2, int y2, int Color, bool Fill );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 91
components/display/tarablessd13x6/ssd13x6_font.h

@@ -1,91 +0,0 @@
-#ifndef _SSD13x6_FONT_H_
-#define _SSD13x6_FONT_H_
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct SSD13x6_Device;
-
-/* 
- * X-GLCD Font format:
- *
- * First byte of glyph is it's width in pixels.
- * Each data byte represents 8 pixels going down from top to bottom.
- * 
- * Example glyph layout for a 16x16 font
- * 'a': [Glyph width][Pixel column 0][Pixel column 1] where the number of pixel columns is the font height divided by 8
- * 'b': [Glyph width][Pixel column 0][Pixel column 1]...
- * 'c': And so on...
- */
-
-struct SSD13x6_FontDef {
-    const uint8_t* FontData;
-
-    int Width;
-    int Height;
-
-    int StartChar;
-    int EndChar;
-
-    bool Monospace;
-};
-
-typedef enum {
-    TextAnchor_East = 0,
-    TextAnchor_West,
-    TextAnchor_North,
-    TextAnchor_South,
-    TextAnchor_NorthEast,
-    TextAnchor_NorthWest,
-    TextAnchor_SouthEast,
-    TextAnchor_SouthWest,
-    TextAnchor_Center
-} TextAnchor;
-
-bool SSD13x6_SetFont( struct SSD13x6_Device* Display, const struct SSD13x6_FontDef* Font );
-
-void SSD13x6_FontForceProportional( struct SSD13x6_Device* Display, bool Force );
-void SSD13x6_FontForceMonospace( struct SSD13x6_Device* Display, bool Force );
-
-int SSD13x6_FontGetWidth( struct SSD13x6_Device* Display );
-int SSD13x6_FontGetHeight( struct SSD13x6_Device* Display );
-
-int SSD13x6_FontGetMaxCharsPerRow( struct SSD13x6_Device* Display );
-int SSD13x6_FontGetMaxCharsPerColumn( struct SSD13x6_Device* Display );
-
-int SSD13x6_FontGetCharWidth( struct SSD13x6_Device* Display, char Character );
-int SSD13x6_FontGetCharHeight( struct SSD13x6_Device* Display );
-int SSD13x6_FontMeasureString( struct SSD13x6_Device* Display, const char* Text );\
-
-void SSD13x6_FontDrawChar( struct SSD13x6_Device* Display, char Character, int x, int y, int Color );
-void SSD13x6_FontDrawString( struct SSD13x6_Device* Display, int x, int y, const char* Text, int Color );
-void SSD13x6_FontDrawAnchoredString( struct SSD13x6_Device* Display, TextAnchor Anchor, const char* Text, int Color );
-void SSD13x6_FontGetAnchoredStringCoords( struct SSD13x6_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text );
-
-extern const struct SSD13x6_FontDef Font_droid_sans_fallback_11x13;
-extern const struct SSD13x6_FontDef Font_droid_sans_fallback_15x17;
-extern const struct SSD13x6_FontDef Font_droid_sans_fallback_24x28;
-
-extern const struct SSD13x6_FontDef Font_droid_sans_mono_7x13;
-extern const struct SSD13x6_FontDef Font_droid_sans_mono_13x24;
-extern const struct SSD13x6_FontDef Font_droid_sans_mono_16x31;
-
-extern const struct SSD13x6_FontDef Font_liberation_mono_9x15;
-extern const struct SSD13x6_FontDef Font_liberation_mono_13x21;
-extern const struct SSD13x6_FontDef Font_liberation_mono_17x30;
-
-extern const struct SSD13x6_FontDef Font_Tarable7Seg_16x32;
-extern const struct SSD13x6_FontDef Font_Tarable7Seg_32x64;
-
-extern const struct SSD13x6_FontDef Font_line_1;
-extern const struct SSD13x6_FontDef Font_line_2;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 1 - 5
components/raop/raop.c

@@ -415,11 +415,7 @@ static void *rtsp_thread(void *arg) {
 	if (sock != -1) closesocket(sock);
 	if (sock != -1) closesocket(sock);
 
 
 #ifndef WIN32
 #ifndef WIN32
-	if (!ctx->joiner) {
-		LOG_ERROR("We shall not be here %u! %x %x", ctx->running);
-	} else {
-		xTaskNotifyGive(ctx->joiner);
-	}	
+	xTaskNotifyGive(ctx->joiner);
 	vTaskSuspend(NULL);
 	vTaskSuspend(NULL);
 #endif
 #endif
 
 

+ 32 - 31
components/squeezelite/display.c

@@ -23,6 +23,9 @@
 #include "squeezelite.h"
 #include "squeezelite.h"
 #include "slimproto.h"
 #include "slimproto.h"
 #include "display.h"
 #include "display.h"
+#include "gds.h"
+#include "gds_text.h"
+#include "gds_draw.h"
 
 
 #pragma pack(push, 1)
 #pragma pack(push, 1)
 
 
@@ -85,8 +88,6 @@ struct ANIC_header {
 
 
 #pragma pack(pop)
 #pragma pack(pop)
 
 
-extern struct outputstate output;
-
 static struct {
 static struct {
 	TaskHandle_t task;
 	TaskHandle_t task;
 	SemaphoreHandle_t mutex;
 	SemaphoreHandle_t mutex;
@@ -212,15 +213,15 @@ bool sb_display_init(void) {
 	static EXT_RAM_ATTR StackType_t xStack[SCROLL_STACK_SIZE] __attribute__ ((aligned (4)));
 	static EXT_RAM_ATTR StackType_t xStack[SCROLL_STACK_SIZE] __attribute__ ((aligned (4)));
 	
 	
 	// no display, just make sure we won't have requests
 	// no display, just make sure we won't have requests
-	if (!display || display->height == 0 || display->width == 0) {
+	if (!display || GDS_GetWidth(display) <= 0 || GDS_GetHeight(display) <= 0) {
 		LOG_INFO("no display for LMS");
 		LOG_INFO("no display for LMS");
 		return false;
 		return false;
 	}	
 	}	
 	
 	
 	// need to force height to 32 maximum
 	// need to force height to 32 maximum
-	displayer.width = display->width;
-	displayer.height = min(display->height, SB_HEIGHT);
-	SETD_width = display->width;
+	displayer.width = GDS_GetWidth(display);
+	displayer.height = min(GDS_GetHeight(display), SB_HEIGHT);
+	SETD_width = displayer.width;
 
 
 	// create visu configuration
 	// create visu configuration
 	visu.bar_gap = 1;
 	visu.bar_gap = 1;
@@ -330,8 +331,8 @@ static void send_server(void) {
 static void server(in_addr_t ip, u16_t hport, u16_t cport) {
 static void server(in_addr_t ip, u16_t hport, u16_t cport) {
 	char msg[32];
 	char msg[32];
 	sprintf(msg, "%s:%hu", inet_ntoa(ip), hport);
 	sprintf(msg, "%s:%hu", inet_ntoa(ip), hport);
-	if (displayer.owned) display->text(DISPLAY_FONT_DEFAULT, DISPLAY_CENTERED, DISPLAY_CLEAR | DISPLAY_UPDATE, msg);
-	SETD_width = display->width;
+	if (displayer.owned) GDS_TextPos(display, GDS_FONT_DEFAULT, GDS_TEXT_CENTERED, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, msg);
+	SETD_width = displayer.width;
 	displayer.dirty = true;
 	displayer.dirty = true;
 	if (notify_chain) (*notify_chain)(ip, hport, cport);
 	if (notify_chain) (*notify_chain)(ip, hport, cport);
 }
 }
@@ -426,8 +427,8 @@ static void show_display_buffer(char *ddram) {
 
 
 	LOG_DEBUG("\n\t%.40s\n\t%.40s", line1, line2);
 	LOG_DEBUG("\n\t%.40s\n\t%.40s", line1, line2);
 
 
-	display->line(1, DISPLAY_LEFT, DISPLAY_CLEAR, line1);	
-	display->line(2, DISPLAY_LEFT, DISPLAY_CLEAR | DISPLAY_UPDATE, line2);	
+	GDS_TextLine(display, 1, GDS_TEXT_LEFT, GDS_TEXT_CLEAR, line1);	
+	GDS_TextLine(display, 2, GDS_TEXT_LEFT, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, line2);	
 }
 }
 
 
 /****************************************************************************************
 /****************************************************************************************
@@ -495,13 +496,13 @@ static void grfe_handler( u8_t *data, int len) {
 	if (displayer.owned) {
 	if (displayer.owned) {
 		// did we have something that might have write on the bottom of a SB_HEIGHT+ display
 		// did we have something that might have write on the bottom of a SB_HEIGHT+ display
 		if (displayer.dirty) {
 		if (displayer.dirty) {
-			display->clear(true);
+			GDS_ClearExt(display, true);
 			displayer.dirty = false;
 			displayer.dirty = false;
 		}	
 		}	
 	
 	
 		// draw new frame
 		// draw new frame
-		display->draw_cbr(data + sizeof(struct grfe_packet), displayer.width, displayer.height);
-		display->update();
+		GDS_DrawBitmapCBR(display, data + sizeof(struct grfe_packet), displayer.width, displayer.height);
+		GDS_Update(display);
 	}	
 	}	
 	
 	
 	xSemaphoreGive(displayer.mutex);
 	xSemaphoreGive(displayer.mutex);
@@ -519,10 +520,10 @@ static void grfb_handler(u8_t *data, int len) {
 	
 	
 	LOG_INFO("brightness %hu", pkt->brightness);
 	LOG_INFO("brightness %hu", pkt->brightness);
 	if (pkt->brightness < 0) {
 	if (pkt->brightness < 0) {
-		display->on(false); 
+		GDS_DisplayOff(display); 
 	} else {
 	} else {
-		display->on(true);
-		display->brightness(pkt->brightness);
+		GDS_DisplayOn(display);
+		GDS_SetContrast(display, pkt->brightness);
 	}
 	}
 }
 }
 
 
@@ -603,8 +604,8 @@ static void grfg_handler(u8_t *data, int len) {
 	
 	
 	// can only write if we really own display
 	// can only write if we really own display
 	if (displayer.owned) {
 	if (displayer.owned) {
-		display->draw_cbr(scroller.frame, scroller.back.width, displayer.height);
-		display->update();
+		GDS_DrawBitmapCBR(display, scroller.frame, scroller.back.width, displayer.height);
+		GDS_Update(display);
 	}	
 	}	
 		
 		
 	// now we can active scrolling, but only if we are not on a small screen
 	// now we can active scrolling, but only if we are not on a small screen
@@ -703,7 +704,7 @@ static void visu_update(void) {
 	visu_export.level = 0;
 	visu_export.level = 0;
 	pthread_mutex_unlock(&visu_export.mutex);
 	pthread_mutex_unlock(&visu_export.mutex);
 
 
-	display->clear(false, false, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1);
+	GDS_ClearExt(display, false, false, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1);
 	
 	
 	for (int i = visu.n; --i >= 0;) {
 	for (int i = visu.n; --i >= 0;) {
 		int x1 = visu.col + visu.border + visu.bar_border + i*(visu.bar_width + visu.bar_gap);
 		int x1 = visu.col + visu.border + visu.bar_border + i*(visu.bar_width + visu.bar_gap);
@@ -713,11 +714,11 @@ static void visu_update(void) {
 		else if (visu.bars[i].max) visu.bars[i].max--;
 		else if (visu.bars[i].max) visu.bars[i].max--;
 			
 			
 		for (int j = 0; j <= visu.bars[i].current; j += 2) 
 		for (int j = 0; j <= visu.bars[i].current; j += 2) 
-			display->draw_line( x1, y1 - j, x1 + visu.bar_width - 1, y1 - j);
+			GDS_DrawLine(display, x1, y1 - j, x1 + visu.bar_width - 1, y1 - j, GDS_COLOR_WHITE);
 			
 			
 		if (visu.bars[i].max > 2) {
 		if (visu.bars[i].max > 2) {
-			display->draw_line( x1, y1 - visu.bars[i].max, x1 + visu.bar_width - 1, y1 - visu.bars[i].max);			
-			display->draw_line( x1, y1 - visu.bars[i].max + 1, x1 + visu.bar_width - 1, y1 - visu.bars[i].max + 1);			
+			GDS_DrawLine(display, x1, y1 - visu.bars[i].max, x1 + visu.bar_width - 1, y1 - visu.bars[i].max, GDS_COLOR_WHITE);			
+			GDS_DrawLine(display, x1, y1 - visu.bars[i].max + 1, x1 + visu.bar_width - 1, y1 - visu.bars[i].max + 1, GDS_COLOR_WHITE);			
 		}	
 		}	
 	}
 	}
 }
 }
@@ -756,7 +757,7 @@ static void visu_handler( u8_t *data, int len) {
 	visu.mode = pkt->which;
 	visu.mode = pkt->which;
 	
 	
 	// little trick to clean the taller screens when switching visu 
 	// little trick to clean the taller screens when switching visu 
-	if (visu.row >= SB_HEIGHT) display->clear(false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1);
+	if (visu.row >= SB_HEIGHT) GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1);
 	
 	
 	if (visu.mode) {
 	if (visu.mode) {
 		if (pkt->count >= 4) {
 		if (pkt->count >= 4) {
@@ -767,17 +768,17 @@ static void visu_handler( u8_t *data, int len) {
 
 
 			visu.width = htonl(pkt->width);
 			visu.width = htonl(pkt->width);
 			visu.height = pkt->height ? pkt->height : SB_HEIGHT;
 			visu.height = pkt->height ? pkt->height : SB_HEIGHT;
-			visu.col = pkt->col < 0 ? display->width + pkt->col : pkt->col;
-			visu.row = pkt->row < 0 ? display->height + pkt->row : pkt->row;
+			visu.col = pkt->col < 0 ? displayer.width + pkt->col : pkt->col;
+			visu.row = pkt->row < 0 ? GDS_GetHeight(display) + pkt->row : pkt->row;
 			visu.border =  htonl(pkt->border);
 			visu.border =  htonl(pkt->border);
 			bars = htonl(pkt->bars);
 			bars = htonl(pkt->bars);
 			visu.spectrum_scale = htonl(pkt->spectrum_scale) / 100.;
 			visu.spectrum_scale = htonl(pkt->spectrum_scale) / 100.;
 		} else {
 		} else {
 			// full screen visu, try to use bottom screen if available
 			// full screen visu, try to use bottom screen if available
-			visu.width = display->width;
-			visu.height = display->height > SB_HEIGHT ? display->height - SB_HEIGHT : display->height;
+			visu.width = displayer.width;
+			visu.height = GDS_GetHeight(display) > SB_HEIGHT ? GDS_GetHeight(display) - SB_HEIGHT : GDS_GetHeight(display);
 			visu.col = visu.border = 0;
 			visu.col = visu.border = 0;
-			visu.row = display->height - visu.height;			
+			visu.row = GDS_GetHeight(display) - visu.height;			
 			bars = htonl(pkt->full.bars);
 			bars = htonl(pkt->full.bars);
 			visu.spectrum_scale = htonl(pkt->full.spectrum_scale) / 100.;
 			visu.spectrum_scale = htonl(pkt->full.spectrum_scale) / 100.;
 		}
 		}
@@ -811,7 +812,7 @@ static void visu_handler( u8_t *data, int len) {
 		// reset bars maximum
 		// reset bars maximum
 		for (int i = visu.n; --i >= 0;) visu.bars[i].max = 0;
 		for (int i = visu.n; --i >= 0;) visu.bars[i].max = 0;
 				
 				
-		display->clear(false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1);
+		GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1);
 		
 		
 		LOG_INFO("Visualizer with %u bars of width %d:%d:%d:%d (%w:%u,h:%u,c:%u,r:%u,s:%.02f)", visu.n, visu.bar_border, visu.bar_width, visu.bar_gap, visu.border, visu.width, visu.height, visu.col, visu.row, visu.spectrum_scale);
 		LOG_INFO("Visualizer with %u bars of width %d:%d:%d:%d (%w:%u,h:%u,c:%u,r:%u,s:%.02f)", visu.n, visu.bar_border, visu.bar_width, visu.bar_gap, visu.border, visu.width, visu.height, visu.col, visu.row, visu.spectrum_scale);
 	} else {
 	} else {
@@ -854,7 +855,7 @@ static void displayer_task(void *args) {
 				memcpy(scroller.frame, scroller.back.frame, scroller.back.width * displayer.height / 8);
 				memcpy(scroller.frame, scroller.back.frame, scroller.back.width * displayer.height / 8);
 				for (int i = 0; i < scroller.width * displayer.height / 8; i++) scroller.frame[i] |= scroller.scroll.frame[scroller.scrolled * displayer.height / 8 + i];
 				for (int i = 0; i < scroller.width * displayer.height / 8; i++) scroller.frame[i] |= scroller.scroll.frame[scroller.scrolled * displayer.height / 8 + i];
 				scroller.scrolled += scroller.by;
 				scroller.scrolled += scroller.by;
-				if (displayer.owned) display->draw_cbr(scroller.frame, scroller.width, displayer.height);	
+				if (displayer.owned) GDS_DrawBitmapCBR(display, scroller.frame, scroller.width, displayer.height);	
 				
 				
 				// short sleep & don't need background update
 				// short sleep & don't need background update
 				scroller.wake = scroller.speed;
 				scroller.wake = scroller.speed;
@@ -884,7 +885,7 @@ static void displayer_task(void *args) {
 		}
 		}
 		
 		
 		// need to make sure we own display
 		// need to make sure we own display
-		if (displayer.owned) display->update();
+		if (displayer.owned) GDS_Update(display);
 		
 		
 		// release semaphore and sleep what's needed
 		// release semaphore and sleep what's needed
 		xSemaphoreGive(displayer.mutex);
 		xSemaphoreGive(displayer.mutex);