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

--- 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