1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-24 00:35:18 +03:00

tmrttmrt/Fixes#2750__Mega2560_ST7920_mixer_freq_too_slow

This commit is contained in:
tmertelj 2015-08-25 10:00:36 +02:00 committed by Tomaz Mertelj
commit 87df5766f0
7 changed files with 100 additions and 11 deletions

View file

@ -10,6 +10,7 @@
<li>Several fixes to the SD card manager menu (<a href=https://github.com/opentx/opentx/issues/2623>#2623</a>)</li>
<li>Fixed the difference between top and main LCD TX battery bars on 9Xe (<a href=https://github.com/opentx/opentx/issues/2671>#2671</a>)</li>
<li>Several Lua getValue() fields were not exported correctly (tx-voltage, clock and timers1-3)</li>
<li>Fixed: Edge Logical Switch could trigger right after the model was loaded or the radio turned on (<a href=https://github.com/opentx/opentx/issues/2728>#2728</a>)</li>
</ul>
[Sky9x / 9XR-PRO]

View file

@ -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

View file

@ -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()) {

View file

@ -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
}

View file

@ -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) {

View file

@ -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

View file

@ -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<yend; y++) {
x_addr = 0;
//Convert coordinates to weirdly-arranged 128x64 screen (the ST7920 is mapped for 256x32 displays)
if (y > 31) {
@ -180,10 +228,18 @@ void lcdRefresh()
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<<OUT_C_LCD_E);
_delay_us(8);
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_E);
@ -216,4 +272,8 @@ void lcdRefresh()
}
#endif
LCD_UNLOCK();
#if defined(LCD_ST7920)
return state;
#endif
}