# HG changeset patch # User Ideenmodellierer # Date 1612731883 -3600 # Node ID ba83a8ef9badfbc87e8a70f7d8aeab8fe520fd02 # Parent 8f78faf88fc56a167a8e5a7bbe4f705ed4d4f2f0 Improvment frame Handling: In previous version, especially during fast menu operations, from time to time a flicker (in case of cyclic updated views) or corrupted menus appeared. Possible root cause is a interferance in the chain: refresh display (~100ms) => release frame (in parallel to) provide frame (~45ms) => clear frame (~45ms). to improve the behaviour the clear frame loop is not iterated until all bufferes are cleared (before one buffer every~45ms). getFrame() does now iterate through all frame buffers instead reusing the first possible (to avoid ghoust views and to provide more time to housekeeping function for cleanup) diff -r 8f78faf88fc5 -r ba83a8ef9bad Discovery/Src/base.c --- a/Discovery/Src/base.c Wed Feb 03 21:45:48 2021 +0100 +++ b/Discovery/Src/base.c Sun Feb 07 22:04:43 2021 +0100 @@ -292,6 +292,7 @@ uint32_t base_tempLightLevel = 0; static uint8_t wasFirmwareUpdateCheckBattery = 0; static uint8_t DoDisplayRefresh = 0; /* trigger to refresh display data */ +static uint8_t DoHousekeeping = 0; /* trigger to cleanup the frame buffers */ /* Private function prototypes -----------------------------------------------*/ static void SystemClock_Config(void); @@ -497,6 +498,10 @@ deco_loop(); TriggerButtonAction(); + if(DoHousekeeping) + { + DoHousekeeping = housekeepingFrame(); + } if(DoDisplayRefresh) /* set every 100ms by timer interrupt */ { DoDisplayRefresh = 0; @@ -509,7 +514,8 @@ updateMiniLiveLogbook(1); RefreshDisplay(); - TimeoutControl(); /* exit menus if needed */ + DoHousekeeping = 0; /* make sure frames are not cleared before they are transferred */ + TimeoutControl(); /* exit menus if needed */ #ifdef ENABLE_MOTION_CONTROL if((stateUsed->mode == MODE_DIVE) && (settingsGetPointer()->MotionDetection != MOTION_DETECT_OFF)) /* handle motion events in divemode only */ @@ -648,7 +654,7 @@ if (GPIO_Pin == VSYNC_IRQ_PIN) // rechts, unten { GFX_change_LTDC(); - housekeepingFrame(); + DoHousekeeping = 1; /* #ifdef DEMOMODE static uint8_t countCall = 0; diff -r 8f78faf88fc5 -r ba83a8ef9bad Discovery/Src/gfx_engine.c --- a/Discovery/Src/gfx_engine.c Wed Feb 03 21:45:48 2021 +0100 +++ b/Discovery/Src/gfx_engine.c Sun Feb 07 22:04:43 2021 +0100 @@ -3375,27 +3375,45 @@ uint32_t getFrame(uint8_t callerId) { + static uint8_t lastFrameProvided = 0; uint8_t i; - i = 0; - while((i < MAXFRAMES) && (frame[i].status != CLEAR)) +/* first iteration: look for a clear frame */ + i = lastFrameProvided; + do + { i++; + if(i == MAXFRAMES) + { + i = 0; + } + } while((i != lastFrameProvided) && (frame[i].status != CLEAR)); if((i < MAXFRAMES) && (frame[i].status == CLEAR)) { frame[i].status = BLOCKED; frame[i].caller = callerId; + lastFrameProvided = i; return frame[i].StartAddress; } - i = 0; - while((i < MAXFRAMES) && (frame[i].status != RELEASED)) +/* second iteration: look for a frame which may be reused after clearing */ + i = lastFrameProvided; + do + { i++; + if(i == MAXFRAMES) + { + i = 0; + } + }while((i < MAXFRAMES) && (frame[i].status != RELEASED)); + if((i < MAXFRAMES) && (frame[i].status == RELEASED)) { GFX_clear_frame_immediately(frame[i].StartAddress); frame[i].status = BLOCKED; + lastFrameProvided = i; return frame[i].StartAddress; } return 0; @@ -3458,47 +3476,52 @@ } -void housekeepingFrame(void) +uint8_t housekeepingFrame(void) { static uint8_t countLogClear = 0; + uint8_t i; + uint8_t retVal = 1; - if(DMA2D_at_work != 255) - return; - - /* new for debug hw 151202 */ - for(int i=1;i