diff --git a/radio/src/gui/9X/lcd.h b/radio/src/gui/9X/lcd.h index 1789429ab..6503e93bc 100644 --- a/radio/src/gui/9X/lcd.h +++ b/radio/src/gui/9X/lcd.h @@ -263,6 +263,13 @@ void lcdInit(); void lcdRefresh(); +#if defined(LCD_ST7920) +uint8_t lcdRefresh_ST7920(uint8_t full); +#define IS_LCD_REFRESH_ALLOWED() (0==lcdstate) +#else +#define IS_LCD_REFRESH_ALLOWED() (1) +#endif + #if defined(BOOT) #define BLINK_ON_PHASE (0) #else diff --git a/radio/src/main_avr.cpp b/radio/src/main_avr.cpp index ac8f0385c..0423d5ea4 100644 --- a/radio/src/main_avr.cpp +++ b/radio/src/main_avr.cpp @@ -43,6 +43,9 @@ void perMain() { #if defined(SIMU) doMixerCalculations(); +#endif +#if defined(LCD_ST7920) + uint8_t lcdstate=0; #endif uint16_t t0 = getTmr16KHz(); int16_t delta = (nextMixerEndTime - lastMixerDuration) - t0; @@ -129,31 +132,36 @@ void perMain() const char *warn = s_warning; uint8_t menu = s_menu_count; - lcd_clear(); - if (menuEvent) { - m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0; - m_posHorz = 0; - evt = menuEvent; - menuEvent = 0; - AUDIO_MENUS(); - } - g_menuStack[g_menuStackPtr]((warn || menu) ? 0 : evt); + if(IS_LCD_REFRESH_ALLOWED()){//No need to redraw until lcdRefresh_ST7920(0) below completely refreshes the display. + lcd_clear(); + if (menuEvent) { + m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0; + m_posHorz = 0; + evt = menuEvent; + menuEvent = 0; + AUDIO_MENUS(); + } + g_menuStack[g_menuStackPtr]((warn || menu) ? 0 : evt); - if (warn) DISPLAY_WARNING(evt); + if (warn) DISPLAY_WARNING(evt); #if defined(NAVIGATION_MENUS) - if (menu) { - const char * result = displayMenu(evt); - if (result) { - menuHandler(result); - putEvent(EVT_MENU_UP); - } + if (menu) { + const char * result = displayMenu(evt); + if (result) { + menuHandler(result); + putEvent(EVT_MENU_UP); + } + } +#endif + drawStatusLine(); } +#if defined(LCD_ST7920) + lcdstate=lcdRefresh_ST7920(0); +#else + lcdRefresh(); #endif - drawStatusLine(); - - lcdRefresh(); #endif if (SLAVE_MODE()) { diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 6185447e8..9db53c206 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -179,6 +179,7 @@ int16_t applyLimits(uint8_t channel, int32_t value) } #endif + int16_t ofs = LIMIT_OFS_RESX(lim); int16_t lim_p = LIMIT_MAX_RESX(lim); int16_t lim_n = LIMIT_MIN_RESX(lim); @@ -1100,7 +1101,7 @@ void evalMixes(uint8_t tick10ms) } } -#if defined(PCBGRUVIN9X) && defined(DEBUG) && !defined(VOICE) +#if (defined(CPU2560) && defined(DEBUG) && !defined(VOICE)) PORTH &= ~0x40; // PORTH:6 HIGH->LOW signals end of mixer interrupt #endif } diff --git a/radio/src/targets/mega2560/board_mega2560.cpp b/radio/src/targets/mega2560/board_mega2560.cpp index d153186df..bc72dd721 100644 --- a/radio/src/targets/mega2560/board_mega2560.cpp +++ b/radio/src/targets/mega2560/board_mega2560.cpp @@ -48,7 +48,11 @@ inline void boardInit() DDRE = 0b00000010; PORTE = 0b11111100; // 7:N/A, 6:N/A, 5:RENC1_B, 4:RENC1_A, 3:N/A, 2:N/A, 1:TELEM_TX, 0:TELEM_RX DDRF = 0b00000000; PORTF = 0b11111111; // 7-0:Trim switch inputs DDRG = 0b00000000; PORTG = 0b11111111; // 7:N/A, 6:N/A, 5:N/A, 4:N/A, 3:N/A, 2:TCut_SW, 1:Gear_SW, 0: RudDr_SW +#if defined(PCBMEGA2560) && defined(DEBUG) + DDRH = 0b01011000; PORTH = 0b11110110; // 7:N/A, 6:RF_Activated, 5:DSC_Activated, 4:Hold_Power, 3:Speaker, 2:N/A, 1:N/A, 0:Haptic +#else DDRH = 0b00011000; PORTH = 0b11110110; // 7:N/A, 6:RF_Activated, 5:DSC_Activated, 4:Hold_Power, 3:Speaker, 2:N/A, 1:N/A, 0:Haptic +#endif DDRJ = 0b00000000; PORTJ = 0b11111111; // 7:N/A, 6:N/A, 5:N/A, 4:N/A, 3:N/A, 2:N/A, 1:RENC2_push, 0:RENC1_push DDRK = 0b00000000; PORTK = 0b00000000; // Analogic input (no pull-ups) DDRL = 0b00000000; PORTL = 0b11111111; // 7:TRN_SW 6:EleDR_SW, 5:ESC, 4:MENU 3:Keyb_Left, 2:Keyb_Right, 1:Keyb_Up, 0:Keyb_Down diff --git a/radio/src/targets/stock/lcd_driver.cpp b/radio/src/targets/stock/lcd_driver.cpp index 1f9821913..450751d89 100644 --- a/radio/src/targets/stock/lcd_driver.cpp +++ b/radio/src/targets/stock/lcd_driver.cpp @@ -150,17 +150,65 @@ void lcdSetRefVolt(uint8_t val) #endif } +#if defined(LCD_ST7920) +void lcdRefresh(){ + lcdRefresh_ST7920(1); +} + +uint8_t lcdRefresh_ST7920(uint8_t full) +{ +#else void lcdRefresh() { +#endif LCD_LOCK(); #if defined(LCD_ST7920) + static uint8_t state; + uint8_t yst,yend; uint8_t x_addr = 0; uint8_t y_addr = 0; uint16_t line_offset = 0; uint8_t col_offset = 0; - uint16_t byte_offset = 0; uint8_t bit_count = 0; - for (uint8_t y=0; y<64; y++) { + uint8_t result; + uint8_t *p; + if(full!=0){ + yst=0; + yend=64; + state=0; + } + else{ + switch (state){//Since writing to ST7920 is too slow we need to split it to five bands. + default: + case 0: + yst=0; + yend=13; + state=1; + break; + case 1: + yst=13; + yend=26; + state=2; + break; + case 2: + yst=26; + yend=39; + state=3; + break; + case 3: + yst=39; + yend=52; + state=4; + break; + case 4: + yst=52; + yend=64; + state=0; + break; + } + } + + for (uint8_t y=yst; y 31) { @@ -170,20 +218,28 @@ void lcdRefresh() else { y_addr = y; } - lcdSendCtl( 0x80 | y_addr ); //Set Vertical Address + lcdSendCtl( 0x80 | y_addr ); //Set Vertical Address _delay_us(49); - lcdSendCtl( 0x80 | x_addr ); //Set Horizontal Address + 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); + p=displayBuf + line_offset + ( x * 8 ); //Calculate the position of the first byte im array + // adressing the bytes sequential and set the bits at the correct position merging them with an OR operation to get all bits in one byte + // the position of the LSB is the right-most position of the byte to the ST7920 + result = ((*p++ & col_offset)!=0?0x80:0); + result|= ((*p++ & col_offset)!=0?0x40:0); + result|= ((*p++ & col_offset)!=0?0x20:0); + result|= ((*p++ & col_offset)!=0?0x10:0); + result|= ((*p++ & col_offset)!=0?0x08:0); + result|= ((*p++ & col_offset)!=0?0x04:0); + result|= ((*p++ & col_offset) !=0?0x02:0); + result|= ((*p++ & col_offset)!=0?0x01:0); + PORTA_LCD_DAT = result; PORTC_LCD_CTRL |= (1<