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