/* * Authors (alphabetical order) * - Andre Bernet * - Andreas Weitl * - Bertrand Songis * - Bryan J. Rentoul (Gruvin) * - Cameron Weeks * - Erez Raviv * - Gabriel Birkus * - Jean-Pierre Parisy * - Karl Szmutny * - Michael Blandford * - Michal Hlavinka * - Pat Mackenzie * - Philip Moss * - Rob Thomson * - Romolo Manfredini * - Thomas Husterer * * opentx is based on code named * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, * er9x by Erez Raviv: http://code.google.com/p/er9x/, * and the original (and ongoing) project by * Thomas Husterer, th9x: http://code.google.com/p/th9x/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include "opentx.h" void lcdSendCtl(uint8_t val) { PORTC_LCD_CTRL &= ~(1<SEG1) 0xA6, //REV = 0: non-reverse display 0xA4, //EON = 0: normal display. non-entire 0xA2, //Select LCD bias 0xC8, //SHL = 1: reverse direction (COM64->COM1) 0x2F, //Control power circuit operation VC=VR=VF=1 0x25, //Select int resistance ratio R2 R1 R0 =5 0x81, //Set reference voltage Mode 0x22, //24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18 0xAF, //DON = 1: display ON 0x60 //Set the display start line to zero #elif defined(LCD_ERC12864FSF) 0xE2, //Initialize the internal functions 0xAE, //DON = 0: display OFF 0xA1, //ADC = 1: reverse direction (SEG132->SEG1) 0xA6, //REV = 0: non-reverse display 0xA4, //EON = 0: normal display. non-entire 0xA3, //Select LCD bias 0xC0, //SHL = 0: normal direction (COM1->COM64) 0x2F, //Control power circuit operation VC=VR=VF=1 0x27, //Select int resistance ratio R2 R1 R0 0x81, //Set reference voltage Mode 0x2D, //24 SV5 SV4 SV3 SV2 SV1 SV0 0xAF //DON = 1: display ON #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) 0xA6, //REV = 0: non-reverse display 0xA4, //EON = 0: normal display. non-entire 0xA2, //Select LCD bias=0 0xC0, //SHL = 0: normal direction (COM1->COM64) 0x2F, //Control power circuit operation VC=VR=VF=1 0x25, //Select int resistance ratio R2 R1 R0 =5 0x81, //Set reference voltage Mode 0x22, //24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18 0xAF //DON = 1: display ON #endif }; inline void lcdInit() { LCD_LOCK(); 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<