From 744c797e30da38683e4988283c0734be6b025a19 Mon Sep 17 00:00:00 2001 From: JivaroFAD Date: Sun, 17 May 2015 20:26:41 +0200 Subject: [PATCH] ST7920 support added for 9x and M2560 boards Merge of olterion ST7920 driver, thanks :) Draft... please check ! --- radio/src/Makefile | 20 ++-- radio/src/targets/stock/lcd_driver.cpp | 145 +++++++++++++++++-------- 2 files changed, 113 insertions(+), 52 deletions(-) diff --git a/radio/src/Makefile b/radio/src/Makefile index be8eb81f8..0419170fa 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -57,6 +57,10 @@ PCB = 9X # PCB revision PCBREV = +# LCD +# Values: DEFAULT, ST7565P, ST7565R, ERC12864FSF, ST7920 +LCD = DEFAULT + # Enable JETI-Telemetry or FrSky Telemetry reception on UART0 # For this option you need to modify your hardware! # More information at [insertURLhere] @@ -681,13 +685,7 @@ ifeq ($(PCB), MEGA2560) BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp - # LCD driver - # Values: ST7565P(default), ST7565R - LCD = ST7565P - ifeq ($(LCD), ST7565R) - CPPDEFS += -DLCD_ST7565R - endif - EXTRABOARDSRC = targets/common_avr/adc_driver.cpp targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp + EXTRABOARDSRC = targets/common_avr/adc_driver.cpp targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp ifeq ($(SDCARD), YES) EXTRABOARDSRC += $(FATFSDIR)/ff.c $(FATFSDIR)/fattime.c $(FATFSDIR)/option/ccsbcs.c targets/gruvin9x/diskio.cpp @@ -1072,6 +1070,14 @@ ifeq ($(TURNIGY_TRANSMITTER_FIX), YES) endif endif +ifeq ($(LCD), ST7565R) + CPPDEFS += -DLCD_ST7565R +else ifeq ($(LCD), ERC12864FSF) + CPPDEFS += -DLCD_ERC12864FSF +else ifeq ($(LCD), ST7920) + CPPDEFS += -DLCD_ST7920 +endif + ifeq ($(AUTOSWITCH), YES) CPPDEFS += -DAUTOSWITCH endif diff --git a/radio/src/targets/stock/lcd_driver.cpp b/radio/src/targets/stock/lcd_driver.cpp index ed5323c47..7eb774336 100644 --- a/radio/src/targets/stock/lcd_driver.cpp +++ b/radio/src/targets/stock/lcd_driver.cpp @@ -47,7 +47,7 @@ void lcdSendCtl(uint8_t val) { PORTC_LCD_CTRL &= ~(1<SEG1) @@ -86,7 +86,7 @@ const static pm_uchar lcdInitSequence[] PROGMEM = 0x22, //24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18 0xAF, //DON = 1: display ON 0x60 //sets the display start line to zero -#elif LCD_ERC12864FSF +#elif defined(LCD_ERC12864FSF) 0xE2, //Initialize the internal functions 0xAE, //DON = 0: display OFF 0xA1, //ADC = 1: reverse direction(SEG132->SEG1) @@ -99,7 +99,13 @@ const static pm_uchar lcdInitSequence[] PROGMEM = 0x81, //Set reference voltage Mode 0x2D, //24 SV5 SV4 SV3 SV2 SV1 SV0 0xAF //DON = 1: display ON -#else +#elif defined(LCD_ST7920) + 0x30, //Set 8-bit interface + 0x36, //Repeat with graphics bit set to ON + 0x0C, //Display ON, cursor and blink OFF + 0x01, //Clear display, reset address + 0x06 //Display ON, no cursor +#else //ST7565P (default 9x LCD) 0xE2, //Initialize the internal functions 0xAE, //DON = 0: display OFF 0xA1, //ADC = 1: reverse direction(SEG132->SEG1) @@ -121,58 +127,107 @@ inline void lcdInit() // ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid= LCD_LOCK(); - PORTC_LCD_CTRL &= ~(1< so some value for both screen and no #ifdef + #endif + PORTC_LCD_CTRL |= (1<0; --x) { - PORTA_LCD_DAT = *p++; - PORTC_LCD_CTRL |= (1< 31) + { + y_addr = y - 32; //Because there are only 31 addressable lines in the ST7920 + x_addr += 8; //so we overflow x (7 visible bytes per line) to reach the bottom half + }else{ + y_addr = y; + } + lcdSendCtl( 0x80 | y_addr ); //Set Vertical Address + _delay_us(49); + lcdSendCtl( 0x80 | x_addr ); //Set Horizontal Address + _delay_us(49); + PORTC_LCD_CTRL |= (1< 0=0, 1=1..7=7, 8=0, 9=1... + col_offset = 1 << bit_count; //Build a value for a AND operation with the vorrect bitposition + line_offset = ( y / 8 ) * 128; //On the ST7565 there are 8 lines with each 128 bytes width + for (coord_t x=0; x < 16; x++) { //Walk through 16 bytes form left to right (128 Pixel) + byte_offset = line_offset + ( x * 8 ); //Calculate the position of the first byte im array + //adressing the bytes sequential and shift the bits at the correct position, afterwards a OR operation to get all bits in one byte + //the position of the LSB is the left-most position of the byte to the ST7920 + PORTA_LCD_DAT = (((displayBuf[byte_offset] & col_offset) >> bit_count) << 7) | (((displayBuf[byte_offset + 1] & col_offset) >> bit_count) << 6) | (((displayBuf[byte_offset + 2] & col_offset) >> bit_count ) << 5) | (((displayBuf[byte_offset + 3] & col_offset) >> bit_count ) << 4) | (((displayBuf[byte_offset + 4] & col_offset) >> bit_count ) << 3) | (((displayBuf[byte_offset + 5] & col_offset) >> bit_count ) << 2) | (((displayBuf[byte_offset + 6] & col_offset) >> bit_count ) << 1) | (((displayBuf[byte_offset + 7] & col_offset) >> bit_count ) << 0); + PORTC_LCD_CTRL |= (1<0; --x) { + PORTA_LCD_DAT = *p++; + PORTC_LCD_CTRL |= (1<