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