You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							459 lines
						
					
					
						
							9.3 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							459 lines
						
					
					
						
							9.3 KiB
						
					
					
				
								--- a/glcddrivers/Makefile
							 | 
						|
								+++ b/glcddrivers/Makefile
							 | 
						|
								@@ -63,6 +63,11 @@
							 | 
						|
								     LIBS += -lwiringPi
							 | 
						|
								 endif
							 | 
						|
								 
							 | 
						|
								+ifeq ($(HAVE_DRIVER_VUPLUS4K), 1)
							 | 
						|
								+    DEFINES += -DHAVE_DRIVER_VUPLUS4K
							 | 
						|
								+    OBJS += vuplus4k.o
							 | 
						|
								+endif
							 | 
						|
								+
							 | 
						|
								 ### Implicit rules:
							 | 
						|
								 
							 | 
						|
								 %.o: %.c
							 | 
						|
								--- a/glcddrivers/drivers.c
							 | 
						|
								+++ b/glcddrivers/drivers.c
							 | 
						|
								@@ -50,6 +50,9 @@
							 | 
						|
								 #ifdef HAVE_DRIVER_ILI9341
							 | 
						|
								 #include "ili9341.h"
							 | 
						|
								 #endif
							 | 
						|
								+#ifdef HAVE_DRIVER_VUPLUS4K
							 | 
						|
								+#include "vuplus4k.h"
							 | 
						|
								+#endif
							 | 
						|
								 
							 | 
						|
								 namespace GLCD
							 | 
						|
								 {
							 | 
						|
								@@ -93,6 +96,9 @@
							 | 
						|
								 #endif
							 | 
						|
								 #ifdef HAVE_DRIVER_ILI9341
							 | 
						|
								     {"ili9341",       kDriverILI9341},
							 | 
						|
								+#endif
							 | 
						|
								+#ifdef HAVE_DRIVER_VUPLUS4K
							 | 
						|
								+    {"vuplus4k",      kDriverVUPLUS4K},
							 | 
						|
								 #endif
							 | 
						|
								     {"",              kDriverUnknown}
							 | 
						|
								 };
							 | 
						|
								@@ -180,6 +186,10 @@
							 | 
						|
								         case kDriverILI9341:
							 | 
						|
								             return new cDriverILI9341(config);
							 | 
						|
								 #endif
							 | 
						|
								+#ifdef HAVE_DRIVER_VUPLUS4K
							 | 
						|
								+        case kDriverVUPLUS4K:
							 | 
						|
								+            return new cDriverVUPLUS4K(config);
							 | 
						|
								+#endif
							 | 
						|
								         case kDriverUnknown:
							 | 
						|
								         default:
							 | 
						|
								             return NULL;
							 | 
						|
								--- a/glcddrivers/driver.h
							 | 
						|
								+++ b/glcddrivers/driver.h
							 | 
						|
								@@ -74,7 +74,7 @@ public:
							 | 
						|
								     virtual void Refresh(bool refreshAll = false) {}
							 | 
						|
								 
							 | 
						|
								     virtual void SetBrightness(unsigned int percent) {}
							 | 
						|
								-
							 | 
						|
								+    virtual void SetMirrorVideo(bool mirror) {}
							 | 
						|
								 
							 | 
						|
								     virtual bool SetFeature  (const std::string & Feature, int value)   { return false; }
							 | 
						|
								 
							 | 
						|
								--- a/glcddrivers/drivers.h
							 | 
						|
								+++ b/glcddrivers/drivers.h
							 | 
						|
								@@ -58,6 +58,9 @@
							 | 
						|
								 #endif
							 | 
						|
								     kDriverUSBserLCD     = 23,
							 | 
						|
								     kDriverST7565RReel   = 24,
							 | 
						|
								+#ifdef HAVE_DRIVER_VUPLUS4K
							 | 
						|
								+    kDriverVUPLUS4K      = 25,
							 | 
						|
								+#endif
							 | 
						|
								     kDriverSerDisp       = 100,
							 | 
						|
								     kDriverG15daemon     = 200
							 | 
						|
								 };
							 | 
						|
								--- /dev/null
							 | 
						|
								+++ b/glcddrivers/vuplus4k.c
							 | 
						|
								@@ -0,0 +1,282 @@
							 | 
						|
								+/*
							 | 
						|
								+ * GraphLCD driver library
							 | 
						|
								+ *
							 | 
						|
								+ * vuplus4k.c  -  VUPLUS4K OLED driver class
							 | 
						|
								+ *
							 | 
						|
								+ * This file is released under the GNU General Public License. Refer
							 | 
						|
								+ * to the COPYING file distributed with this package.
							 | 
						|
								+ *
							 | 
						|
								+ * (c) redblue 2019
							 | 
						|
								+ */
							 | 
						|
								+
							 | 
						|
								+
							 | 
						|
								+#include <stdio.h>
							 | 
						|
								+#include <stdlib.h>
							 | 
						|
								+#include <unistd.h>
							 | 
						|
								+#include <fcntl.h>
							 | 
						|
								+#include <sys/ioctl.h>
							 | 
						|
								+#include <string.h>
							 | 
						|
								+#include <stdint.h>
							 | 
						|
								+#include <syslog.h>
							 | 
						|
								+#include <cstring>
							 | 
						|
								+#include <byteswap.h>
							 | 
						|
								+
							 | 
						|
								+#include "common.h"
							 | 
						|
								+#include "config.h"
							 | 
						|
								+#include "vuplus4k.h"
							 | 
						|
								+
							 | 
						|
								+namespace GLCD
							 | 
						|
								+{
							 | 
						|
								+
							 | 
						|
								+cDriverVUPLUS4K::cDriverVUPLUS4K(cDriverConfig * config)
							 | 
						|
								+:	cDriver(config),
							 | 
						|
								+	fd(-1)
							 | 
						|
								+{
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+cDriverVUPLUS4K::~cDriverVUPLUS4K()
							 | 
						|
								+{
							 | 
						|
								+	DeInit();
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+int lcd_read_value(const char *filename)
							 | 
						|
								+{
							 | 
						|
								+	int value = 0;
							 | 
						|
								+	FILE *fd = fopen(filename, "r");
							 | 
						|
								+	if (fd) {
							 | 
						|
								+		int tmp;
							 | 
						|
								+		if (fscanf(fd, "%x", &tmp) == 1)
							 | 
						|
								+			value = tmp;
							 | 
						|
								+		fclose(fd);
							 | 
						|
								+	}
							 | 
						|
								+	return value;
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+int cDriverVUPLUS4K::Init()
							 | 
						|
								+{
							 | 
						|
								+	int x;
							 | 
						|
								+
							 | 
						|
								+	width = config->width;
							 | 
						|
								+	if (width <= 0)
							 | 
						|
								+		width = lcd_read_value(XRES);
							 | 
						|
								+
							 | 
						|
								+	height = config->height;
							 | 
						|
								+	if (height <= 0)
							 | 
						|
								+		height = lcd_read_value(YRES);
							 | 
						|
								+
							 | 
						|
								+	bpp = lcd_read_value(BPP);
							 | 
						|
								+
							 | 
						|
								+	switch (bpp)
							 | 
						|
								+	{
							 | 
						|
								+		case 8:
							 | 
						|
								+			stride_bpp_value = 1;
							 | 
						|
								+			break;
							 | 
						|
								+		case 15:
							 | 
						|
								+		case 16:
							 | 
						|
								+			stride_bpp_value = 2;
							 | 
						|
								+			break;
							 | 
						|
								+		case 24:
							 | 
						|
								+		case 32:
							 | 
						|
								+			stride_bpp_value = 4;
							 | 
						|
								+			break;
							 | 
						|
								+		default:
							 | 
						|
								+			stride_bpp_value = (bpp + 7) / 8;
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	stride = width * stride_bpp_value;
							 | 
						|
								+
							 | 
						|
								+	for (unsigned int i = 0; i < config->options.size(); i++)
							 | 
						|
								+	{
							 | 
						|
								+		if (config->options[i].name == "")
							 | 
						|
								+		{
							 | 
						|
								+		}
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	if (config->device == "")
							 | 
						|
								+	{
							 | 
						|
								+		fd = open("/dev/dbox/lcd0", O_RDWR);
							 | 
						|
								+		if (fd == -1)
							 | 
						|
								+			fd = open("/dev/lcd0", O_RDWR);
							 | 
						|
								+		if (fd == -1)
							 | 
						|
								+			fd = open("/dev/dbox/oled0", O_RDWR);
							 | 
						|
								+		if (fd == -1)
							 | 
						|
								+			fd = open("/dev/oled0", O_RDWR);
							 | 
						|
								+	}
							 | 
						|
								+	else
							 | 
						|
								+	{
							 | 
						|
								+		fd = open(config->device.c_str(), O_RDWR);
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	if (fd == -1) {
							 | 
						|
								+		printf("cannot open lcd device\n");
							 | 
						|
								+		return -1;
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	int tmp = LCD_MODE_BIN;
							 | 
						|
								+	if (ioctl(fd, LCD_IOCTL_ASC_MODE, &tmp)) {
							 | 
						|
								+		printf("failed to set lcd bin mode\n");
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	newLCD = new uint16_t[height * stride];
							 | 
						|
								+	if (newLCD)
							 | 
						|
								+		memset(newLCD, 0, height * stride);
							 | 
						|
								+	oldLCD = new uint16_t[height * stride];
							 | 
						|
								+	if (oldLCD)
							 | 
						|
								+		memset(oldLCD, 0, height * stride);
							 | 
						|
								+
							 | 
						|
								+	syslog(LOG_INFO, "%s: current lcd is %dx%d, %dbpp, vuplus4k lcd device was opened successfully\n", config->name.c_str(), width, height, bpp);
							 | 
						|
								+
							 | 
						|
								+	*oldConfig = *config;
							 | 
						|
								+
							 | 
						|
								+	// clear display
							 | 
						|
								+	Clear();
							 | 
						|
								+	//Refresh(true);
							 | 
						|
								+
							 | 
						|
								+	syslog(LOG_INFO, "%s: VUPLUS4K initialized.\n", config->name.c_str());
							 | 
						|
								+	return 0;
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+int cDriverVUPLUS4K::DeInit()
							 | 
						|
								+{
							 | 
						|
								+	if (newLCD)
							 | 
						|
								+	{
							 | 
						|
								+		delete[] newLCD;
							 | 
						|
								+		newLCD = 0;
							 | 
						|
								+	}
							 | 
						|
								+	if (oldLCD)
							 | 
						|
								+	{
							 | 
						|
								+		delete[] oldLCD;
							 | 
						|
								+		oldLCD = 0;
							 | 
						|
								+	}
							 | 
						|
								+	if (-1 != fd)
							 | 
						|
								+	{
							 | 
						|
								+        	close(fd);
							 | 
						|
								+		fd=-1;
							 | 
						|
								+	}
							 | 
						|
								+	return 0;
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+int cDriverVUPLUS4K::CheckSetup()
							 | 
						|
								+{
							 | 
						|
								+	if (config->width != oldConfig->width ||
							 | 
						|
								+		config->height != oldConfig->height)
							 | 
						|
								+	{
							 | 
						|
								+		DeInit();
							 | 
						|
								+		Init();
							 | 
						|
								+		return 0;
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	if (config->upsideDown != oldConfig->upsideDown ||
							 | 
						|
								+		config->invert != oldConfig->invert)
							 | 
						|
								+	{
							 | 
						|
								+		oldConfig->upsideDown = config->upsideDown;
							 | 
						|
								+		oldConfig->invert = config->invert;
							 | 
						|
								+		return 1;
							 | 
						|
								+	}
							 | 
						|
								+	return 0;
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+void cDriverVUPLUS4K::Clear()
							 | 
						|
								+{
							 | 
						|
								+	memset(newLCD, 0, width * height);
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+void cDriverVUPLUS4K::SetPixel(int x, int y, uint32_t data)
							 | 
						|
								+{
							 | 
						|
								+	if (x >= width || y >= height)
							 | 
						|
								+		return;
							 | 
						|
								+
							 | 
						|
								+	if (config->upsideDown)
							 | 
						|
								+	{
							 | 
						|
								+		x = width - 1 - x;
							 | 
						|
								+		y = height - 1 - y;
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	uint32_t red, green, blue;
							 | 
						|
								+	blue = (data & 0x000000FF) >> 0;
							 | 
						|
								+	green = (data & 0x0000FF00) >> 8;
							 | 
						|
								+	red = (data & 0x00FF0000) >> 16;
							 | 
						|
								+
							 | 
						|
								+	unsigned char* row_pointers_bit_shift = (unsigned char*) &newLCD[0];
							 | 
						|
								+	int row_pointers_2_ptr = (y * width + x) * stride_bpp_value;
							 | 
						|
								+
							 | 
						|
								+ 	if (config->invert) {
							 | 
						|
								+		blue = 255 - blue;
							 | 
						|
								+		green = 255 - green;
							 | 
						|
								+		red = 255 - red;
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	row_pointers_bit_shift[row_pointers_2_ptr+0]=blue;
							 | 
						|
								+	row_pointers_bit_shift[row_pointers_2_ptr+1]=green;
							 | 
						|
								+	row_pointers_bit_shift[row_pointers_2_ptr+2]=red;
							 | 
						|
								+	row_pointers_bit_shift[row_pointers_2_ptr+3]=0xff;
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+void cDriverVUPLUS4K::Refresh(bool refreshAll)
							 | 
						|
								+{
							 | 
						|
								+	int i;
							 | 
						|
								+	char fileName[256];
							 | 
						|
								+	char str[32];
							 | 
						|
								+	FILE * fp;
							 | 
						|
								+	unsigned char c;
							 | 
						|
								+
							 | 
						|
								+	if (CheckSetup() > 0)
							 | 
						|
								+		refreshAll = true;
							 | 
						|
								+
							 | 
						|
								+	for (i = 0; i < height * stride; i++)
							 | 
						|
								+	{
							 | 
						|
								+		if (newLCD[i] != oldLCD[i])
							 | 
						|
								+		{
							 | 
						|
								+			refreshAll = true;
							 | 
						|
								+			break;
							 | 
						|
								+		}
							 | 
						|
								+	}
							 | 
						|
								+
							 | 
						|
								+	if (refreshAll)
							 | 
						|
								+	{
							 | 
						|
								+		for (i = 0; i < height * stride; i++)
							 | 
						|
								+		{
							 | 
						|
								+			oldLCD[i] = newLCD[i];
							 | 
						|
								+		}
							 | 
						|
								+		unsigned char* row_pointers_bit_shift = (unsigned char*) &newLCD[0];
							 | 
						|
								+		{
							 | 
						|
								+			write(fd, row_pointers_bit_shift, height * stride);
							 | 
						|
								+		}
							 | 
						|
								+	}
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+void cDriverVUPLUS4K::SetBrightness(unsigned int brightness)
							 | 
						|
								+{
							 | 
						|
								+	int value = 0;
							 | 
						|
								+	value = 255 * brightness / 10;
							 | 
						|
								+
							 | 
						|
								+	FILE *f = fopen("/proc/stb/lcd/oled_brightness", "w");
							 | 
						|
								+	if (!f)
							 | 
						|
								+		f = fopen("/proc/stb/fp/oled_brightness", "w");
							 | 
						|
								+	if (f)
							 | 
						|
								+	{
							 | 
						|
								+		if (fprintf(f, "%d", value) == 0)
							 | 
						|
								+			printf("write /proc/stb/lcd/oled_brightness failed!! (%m)\n");
							 | 
						|
								+		fclose(f);
							 | 
						|
								+	}
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+void cDriverVUPLUS4K::SetMirrorVideo(bool mirror)
							 | 
						|
								+{
							 | 
						|
								+	const char *value = "";
							 | 
						|
								+
							 | 
						|
								+	if (mirror)
							 | 
						|
								+		value = "enable";
							 | 
						|
								+	else
							 | 
						|
								+		value = "disable";
							 | 
						|
								+
							 | 
						|
								+	FILE *f = fopen("/proc/stb/lcd/live_enable", "w");
							 | 
						|
								+	if (f)
							 | 
						|
								+	{
							 | 
						|
								+		if (fprintf(f, "%s", value) == 0)
							 | 
						|
								+			printf("write /proc/stb/lcd/live_enable failed!! (%m)\n");
							 | 
						|
								+		fclose(f);
							 | 
						|
								+	}
							 | 
						|
								+}
							 | 
						|
								+
							 | 
						|
								+} // end of namespace
							 | 
						|
								--- /dev/null
							 | 
						|
								+++ b/glcddrivers/vuplus4k.h
							 | 
						|
								@@ -0,0 +1,65 @@
							 | 
						|
								+/*
							 | 
						|
								+ * GraphLCD driver library
							 | 
						|
								+ *
							 | 
						|
								+ * vuplus4k.c  -  VUPLUS4K OLED driver class
							 | 
						|
								+ *
							 | 
						|
								+ * This file is released under the GNU General Public License. Refer
							 | 
						|
								+ * to the COPYING file distributed with this package.
							 | 
						|
								+ *
							 | 
						|
								+ * (c) redblue
							 | 
						|
								+ */
							 | 
						|
								+
							 | 
						|
								+
							 | 
						|
								+#ifndef _GLCDDRIVERS_VUPLUS4K_H_
							 | 
						|
								+#define _GLCDDRIVERS_VUPLUS4K_H_
							 | 
						|
								+
							 | 
						|
								+#include "driver.h"
							 | 
						|
								+
							 | 
						|
								+namespace GLCD
							 | 
						|
								+{
							 | 
						|
								+
							 | 
						|
								+#define XRES "/proc/stb/lcd/xres"
							 | 
						|
								+#define YRES "/proc/stb/lcd/yres"
							 | 
						|
								+#define BPP "/proc/stb/lcd/bpp"
							 | 
						|
								+
							 | 
						|
								+#ifndef LCD_IOCTL_ASC_MODE
							 | 
						|
								+#define LCDSET                          0x1000
							 | 
						|
								+#define LCD_IOCTL_ASC_MODE              (21|LCDSET)
							 | 
						|
								+#define LCD_MODE_ASC                    0
							 | 
						|
								+#define LCD_MODE_BIN                    1
							 | 
						|
								+#endif
							 | 
						|
								+
							 | 
						|
								+#define FP_IOCTL_LCD_DIMM       3
							 | 
						|
								+
							 | 
						|
								+class cDriverConfig;
							 | 
						|
								+
							 | 
						|
								+class cDriverVUPLUS4K : public cDriver
							 | 
						|
								+{
							 | 
						|
								+private:
							 | 
						|
								+	int fd;
							 | 
						|
								+	uint16_t * newLCD;
							 | 
						|
								+	uint16_t * oldLCD;
							 | 
						|
								+	int bpp;
							 | 
						|
								+	int stride;
							 | 
						|
								+	int stride_bpp_value;
							 | 
						|
								+
							 | 
						|
								+	int CheckSetup();
							 | 
						|
								+
							 | 
						|
								+public:
							 | 
						|
								+	cDriverVUPLUS4K(cDriverConfig * config);
							 | 
						|
								+	virtual ~cDriverVUPLUS4K();
							 | 
						|
								+
							 | 
						|
								+	virtual int Init();
							 | 
						|
								+	virtual int DeInit();
							 | 
						|
								+
							 | 
						|
								+	virtual void Clear();
							 | 
						|
								+	virtual void SetPixel(int x, int y, uint32_t data);
							 | 
						|
								+	//virtual void Set8Pixels(int x, int y, unsigned char data);
							 | 
						|
								+	virtual void Refresh(bool refreshAll = false);
							 | 
						|
								+	virtual void SetBrightness(unsigned int percent);
							 | 
						|
								+	virtual void SetMirrorVideo(bool mirror);
							 | 
						|
								+};
							 | 
						|
								+
							 | 
						|
								+} // end of namespace
							 | 
						|
								+
							 | 
						|
								+#endif
							 | 
						|
								--- a/Make.config
							 | 
						|
								+++ b/Make.config
							 | 
						|
								@@ -83,3 +83,6 @@
							 | 
						|
								 #HAVE_DRIVER_SSD1306=1
							 | 
						|
								 
							 | 
						|
								 #HAVE_DRIVER_ILI9341=1
							 | 
						|
								+
							 | 
						|
								+# uncomment this variable if you want to enable the experimental support for vuplus4k
							 | 
						|
								+HAVE_DRIVER_VUPLUS4K=1
							 | 
						|
								--- a/README
							 | 
						|
								+++ b/README
							 | 
						|
								@@ -28,6 +28,7 @@
							 | 
						|
								     futaba md166 driver by     Andreas Brachold <vdr07 AT deltab de>
							 | 
						|
								     usbserlcd driver by        Manuel Reimer <manuel.reimer AT gmx.de>
							 | 
						|
								     st7565r-reel driver by     Georg Acher, BayCom GmbH based on simlcd.c by Carsten Siebholz, ported by Ufuk Altinkaynak
							 | 
						|
								+    vuplus4k oled driver by    redblue <redblue.pkt at orange pl>
							 | 
						|
								 
							 | 
						|
								 Project's homepage: https://projects.vdr-developer.org/projects/graphlcd-base
							 | 
						|
								 GIT repo: https://projects.vdr-developer.org/git/graphlcd-base.git
							 | 
						|
								--- a/graphlcd.conf
							 | 
						|
								+++ b/graphlcd.conf
							 | 
						|
								@@ -117,6 +117,14 @@
							 | 
						|
								 
							 | 
						|
								 ########################################################################
							 | 
						|
								 
							 | 
						|
								+[vuplus4k]
							 | 
						|
								+#  Driver setting for the OLED VUPLUS4K
							 | 
						|
								+Driver=vuplus4k
							 | 
						|
								+#Width=480
							 | 
						|
								+#Height=320
							 | 
						|
								+
							 | 
						|
								+########################################################################
							 | 
						|
								+
							 | 
						|
								 [ax206dpf]
							 | 
						|
								 #  THIS IS AN EXPERIMENTAL DRIVER!
							 | 
						|
								 #  You have to uncomment the variable HAVE_DRIVER_AX206DPF
							 | 
						|
								
							 |