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<