diff --git a/radio/releasenotes.txt b/radio/releasenotes.txt index 404a6db18..3aaa5cf6b 100644 --- a/radio/releasenotes.txt +++ b/radio/releasenotes.txt @@ -10,6 +10,7 @@
  • Several fixes to the SD card manager menu (#2623)
  • Fixed the difference between top and main LCD TX battery bars on 9Xe (#2671)
  • Several Lua getValue() fields were not exported correctly (tx-voltage, clock and timers1-3)
  • +
  • Fixed: Edge Logical Switch could trigger right after the model was loaded or the radio turned on (#2728)
  • [Sky9x / 9XR-PRO] diff --git a/radio/src/gui/9X/lcd.h b/radio/src/gui/9X/lcd.h index 1789429ab..f196b313e 100755 --- a/radio/src/gui/9X/lcd.h +++ b/radio/src/gui/9X/lcd.h @@ -263,6 +263,10 @@ void lcdInit(); void lcdRefresh(); +#if defined(LCD_ST7920) +uint8_t lcdRefresh_ST7920(uint8_t full); +#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..bc813c6b6 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,6 +132,9 @@ void perMain() const char *warn = s_warning; uint8_t menu = s_menu_count; +#if defined(LCD_ST7920) + if(0==lcdstate){//No need to redraw until lcdRefresh_ST7920(0) below completely refreshes the display. +#endif lcd_clear(); if (menuEvent) { m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0; @@ -153,7 +159,13 @@ void perMain() drawStatusLine(); +#if defined(LCD_ST7920) + } + lcdstate=lcdRefresh_ST7920(0); +#else lcdRefresh(); +#endif + #endif if (SLAVE_MODE()) { diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index aefdb9732..fcb871da1 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); @@ -1097,7 +1098,7 @@ void evalMixes(uint8_t tick10ms) } } -#if defined(PCBGRUVIN9X) && defined(DEBUG) && !defined(VOICE) +#if (defined(PCBMEGA2560) || defined(PCBGRUVIN9X)) && defined(DEBUG) && !defined(VOICE) PORTH &= ~0x40; // PORTH:6 HIGH->LOW signals end of mixer interrupt #endif } diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 746e37755..6415699ff 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -835,6 +835,13 @@ void logicalSwitchesTimerTick() #if defined(CPUARM) else if (ls->func == LS_FUNC_EDGE) { ls_stay_struct & lastValue = (ls_stay_struct &)LS_LAST_VALUE(fm, i); + // if this ls was reset by the logicalSwitchesReset() the lastValue will be set to CS_LAST_VALUE_INIT(0x8000) + // when it is unpacked into ls_stay_struct the lastValue.duration will have a value of 0x4000 + // this will produce an instant true for edge logical switch if the second parameter is big enough. + // So we reset it here. + if (LS_LAST_VALUE(fm, i) == CS_LAST_VALUE_INIT) { + lastValue.duration = 0; + } lastValue.state = false; bool state = getSwitch(ls->v1); if (state) { diff --git a/radio/src/targets/mega2560/board_mega2560.cpp b/radio/src/targets/mega2560/board_mega2560.cpp index 30026111f..39b329ec6 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<