comparison Discovery/Src/gfx_engine.c @ 698:2c2b9c6eb089

Bugfix Empty menu: In previous version an empty menu was shown sporadically. After pressing back button the menu was shown correctly again. Potential root cause is the call of the Set Top/Bottom Frame function while updating the cursor position. To handle multible updated is previous toggle bugger has been changed into a ringbuffer allowing to send several update frames after each other. Beside this some old debug code has been removed.
author Ideenmodellierer
date Sun, 25 Sep 2022 21:13:45 +0200
parents 7fa5ef6ae419
children 01f40cb1057e
comparison
equal deleted inserted replaced
697:d55817a11f4c 698:2c2b9c6eb089
34 34
35 /* Exported variables --------------------------------------------------------*/ 35 /* Exported variables --------------------------------------------------------*/
36 36
37 /* Private types -------------------------------------------------------------*/ 37 /* Private types -------------------------------------------------------------*/
38 38
39 #define RING_BUF_SIZE (5u)
40
39 typedef struct 41 typedef struct
40 { 42 {
41 uint32_t Xdelta; 43 uint32_t Xdelta;
42 uint32_t Ydelta; 44 uint32_t Ydelta;
43 uint8_t invert; 45 uint8_t invert;
70 } GFX_layersTopBottom; 72 } GFX_layersTopBottom;
71 */ 73 */
72 typedef struct 74 typedef struct
73 { 75 {
74 uint32_t pActualTopBuffer; 76 uint32_t pActualTopBuffer;
75 uint32_t pNextTopBuffer[2]; 77 uint32_t pNextTopBuffer[RING_BUF_SIZE];
76 GFX_layerSingle actualBottom; 78 GFX_layerSingle actualBottom;
77 GFX_layerSingle nextBottom[2]; 79 GFX_layerSingle nextBottom[RING_BUF_SIZE];
78 uint8_t boolNextTop; 80 uint8_t NextTopWrite;
79 uint8_t boolNextBottom; 81 uint8_t NextBottomWrite;
82 uint8_t NextTopRead;
83 uint8_t NextBottomRead;
80 } GFX_layerControl; 84 } GFX_layerControl;
81 85
82 typedef struct 86 typedef struct
83 { 87 {
84 uint32_t StartAddress; 88 uint32_t StartAddress;
127 static uint8_t logoStatus; 131 static uint8_t logoStatus;
128 static uint32_t pBackgroundHwFrame = 0; 132 static uint32_t pBackgroundHwFrame = 0;
129 static uint8_t backgroundHwStatus; 133 static uint8_t backgroundHwStatus;
130 134
131 static SFrameList frame[MAXFRAMES]; 135 static SFrameList frame[MAXFRAMES];
132
133 #define MAXFRAMECOUNTER (28)
134 static uint8_t frameCounter[MAXFRAMECOUNTER] = { 0 };
135
136 static _Bool lock_changeLTDC = 0;
137 136
138 static void GFX_clear_frame_immediately(uint32_t pDestination); 137 static void GFX_clear_frame_immediately(uint32_t pDestination);
139 static void GFX_draw_image_color(GFX_DrawCfgScreen *hgfx, SWindowGimpStyle window, const tImage *image); 138 static void GFX_draw_image_color(GFX_DrawCfgScreen *hgfx, SWindowGimpStyle window, const tImage *image);
140 /* ITM Trace-----------------------------------------------------------------*/ 139 /* ITM Trace-----------------------------------------------------------------*/
141 140
330 frame[i].StartAddress = frame[i-1].StartAddress + FBOffsetEachIndex; 329 frame[i].StartAddress = frame[i-1].StartAddress + FBOffsetEachIndex;
331 GFX_clear_frame_immediately(frame[i].StartAddress); 330 GFX_clear_frame_immediately(frame[i].StartAddress);
332 frame[i].status = CLEAR; 331 frame[i].status = CLEAR;
333 frame[i].caller = 0; 332 frame[i].caller = 0;
334 } 333 }
335
336 for(int i=1;i<MAXFRAMECOUNTER;i++)
337 {
338 frameCounter[i] = 0;
339 }
340 334
341 pInvisibleFrame = getFrame(2); 335 pInvisibleFrame = getFrame(2);
342 *pDestinationOut = pInvisibleFrame; 336 *pDestinationOut = pInvisibleFrame;
343 337
344 GFX_build_logo_frame(); 338 GFX_build_logo_frame();
366 } 360 }
367 361
368 362
369 void GFX_SetFrameTop(uint32_t pDestination) 363 void GFX_SetFrameTop(uint32_t pDestination)
370 { 364 {
371 lock_changeLTDC = 1; 365 uint8_t NextTopWork = FrameHandler.NextTopWrite + 1;
372 uint8_t boolNextTop = !FrameHandler.boolNextTop; 366
367 if(NextTopWork == RING_BUF_SIZE)
368 {
369 NextTopWork = 0;
370 }
373 371
374 if(pDestination == 0) 372 if(pDestination == 0)
375 pDestination = pInvisibleFrame; 373 pDestination = pInvisibleFrame;
376 374
377 FrameHandler.pNextTopBuffer[boolNextTop] = pDestination; 375 FrameHandler.pNextTopBuffer[NextTopWork] = pDestination;
378 FrameHandler.boolNextTop = boolNextTop; 376 FrameHandler.NextTopWrite = NextTopWork;
379 lock_changeLTDC = 0;
380 } 377 }
381 378
382 379
383 void GFX_SetFrameBottom(uint32_t pDestination, uint32_t x0, uint32_t y0, uint32_t width, uint32_t height) 380 void GFX_SetFrameBottom(uint32_t pDestination, uint32_t x0, uint32_t y0, uint32_t width, uint32_t height)
384 { 381 {
385 lock_changeLTDC = 1; 382 uint8_t NextBottomWork = FrameHandler.NextBottomWrite + 1;
386 uint8_t boolNextBottom = !FrameHandler.boolNextBottom; 383
384 if(NextBottomWork == RING_BUF_SIZE)
385 {
386 NextBottomWork = 0;
387 }
387 388
388 if(pDestination == 0) 389 if(pDestination == 0)
389 pDestination = pInvisibleFrame; 390 pDestination = pInvisibleFrame;
390 391
391 FrameHandler.nextBottom[boolNextBottom].pBuffer = pDestination; 392 FrameHandler.nextBottom[NextBottomWork].pBuffer = pDestination;
392 FrameHandler.nextBottom[boolNextBottom].height = height; 393 FrameHandler.nextBottom[NextBottomWork].height = height;
393 FrameHandler.nextBottom[boolNextBottom].width = width; 394 FrameHandler.nextBottom[NextBottomWork].width = width;
394 FrameHandler.nextBottom[boolNextBottom].leftStart = x0; 395 FrameHandler.nextBottom[NextBottomWork].leftStart = x0;
395 FrameHandler.nextBottom[boolNextBottom].bottomStart = y0; 396 FrameHandler.nextBottom[NextBottomWork].bottomStart = y0;
396 FrameHandler.boolNextBottom = boolNextBottom; 397 FrameHandler.NextBottomWrite = NextBottomWork;
397 lock_changeLTDC = 0;
398 } 398 }
399 399
400 400
401 void GFX_SetFramesTopBottom(uint32_t pTop, uint32_t pBottom, uint32_t heightBottom) 401 void GFX_SetFramesTopBottom(uint32_t pTop, uint32_t pBottom, uint32_t heightBottom)
402 { 402 {
432 } 432 }
433 433
434 434
435 void GFX_change_LTDC(void) 435 void GFX_change_LTDC(void)
436 { 436 {
437 if(lock_changeLTDC == 1)
438 return;
439
440 uint32_t pTop = 0; 437 uint32_t pTop = 0;
441 uint32_t pBot = 0; 438 uint32_t pBot = 0;
442 uint32_t heightBot = 0; 439 uint32_t heightBot = 0;
443 uint32_t widthBot = 0; 440 uint32_t widthBot = 0;
444 uint32_t leftStartBot = 0; 441 uint32_t leftStartBot = 0;
445 uint32_t bottomStartBot = 0; 442 uint32_t bottomStartBot = 0;
446 uint8_t change_position = 0; 443 uint8_t change_position = 0;
447 uint8_t change_size = 0; 444 uint8_t change_size = 0;
445 uint8_t nextBottomBackup = FrameHandler.NextBottomRead; /* Restore entry value in case off logo handling */
448 446
449 // Top Frame 447 // Top Frame
450 pTop = FrameHandler.pNextTopBuffer[FrameHandler.boolNextTop]; 448 if(FrameHandler.NextTopRead != FrameHandler.NextTopWrite)
449 {
450 FrameHandler.NextTopRead++;
451 if(FrameHandler.NextTopRead == RING_BUF_SIZE)
452 {
453 FrameHandler.NextTopRead = 0;
454 }
455 }
456 pTop = FrameHandler.pNextTopBuffer[FrameHandler.NextTopRead];
457
451 if(FrameHandler.pActualTopBuffer != pTop) 458 if(FrameHandler.pActualTopBuffer != pTop)
452 { 459 {
453 HAL_LTDC_SetAddress(&LtdcHandle, pTop, 1); 460 HAL_LTDC_SetAddress(&LtdcHandle, pTop, 1);
454 FrameHandler.pActualTopBuffer = pTop; 461 FrameHandler.pActualTopBuffer = pTop;
455 } 462 }
456 463
457 // Bottom Frame 464 // Bottom Frame
465 if(FrameHandler.NextBottomRead != FrameHandler.NextBottomWrite)
466 {
467 FrameHandler.NextBottomRead++;
468 if(FrameHandler.NextBottomRead == RING_BUF_SIZE)
469 {
470 FrameHandler.NextBottomRead = 0;
471 }
472 }
458 if(logoStatus != LOGOOFF) 473 if(logoStatus != LOGOOFF)
459 { 474 {
460 switch(logoStatus) 475 switch(logoStatus)
461 { 476 {
462 case LOGOSTART: 477 case LOGOSTART:
465 HAL_LTDC_ConfigCLUT(&LtdcHandle, (uint32_t *)indexHWcolor, indexHWcolorSIZE, 0); 480 HAL_LTDC_ConfigCLUT(&LtdcHandle, (uint32_t *)indexHWcolor, indexHWcolorSIZE, 0);
466 HAL_LTDC_SetAddress(&LtdcHandle, pLogoFrame, 0); 481 HAL_LTDC_SetAddress(&LtdcHandle, pLogoFrame, 0);
467 HAL_LTDC_SetWindowSize(&LtdcHandle, 480, 800, 0); 482 HAL_LTDC_SetWindowSize(&LtdcHandle, 480, 800, 0);
468 HAL_LTDC_SetWindowPosition(&LtdcHandle, 0, 0, 0); 483 HAL_LTDC_SetWindowPosition(&LtdcHandle, 0, 0, 0);
469 logoStatus = 2; 484 logoStatus = 2;
485 FrameHandler.NextBottomRead = nextBottomBackup;
470 break; 486 break;
471 487
472 case LOGOSTOP: 488 case LOGOSTOP:
473 HAL_LTDC_SetAlpha(&LtdcHandle, 255, 1); 489 HAL_LTDC_SetAlpha(&LtdcHandle, 255, 1);
474 HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, 0); 490 HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, 0);
475 491
476 pBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].pBuffer; 492 pBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].pBuffer;
477 heightBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].height; 493 heightBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].height;
478 widthBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].width; 494 widthBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].width;
479 leftStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].leftStart; 495 leftStartBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].leftStart;
480 bottomStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].bottomStart; 496 bottomStartBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].bottomStart;
481 HAL_LTDC_SetWindowSize(&LtdcHandle, heightBot, widthBot, 0); 497 HAL_LTDC_SetWindowSize(&LtdcHandle, heightBot, widthBot, 0);
482 HAL_LTDC_SetWindowPosition(&LtdcHandle, bottomStartBot, leftStartBot, 0); 498 HAL_LTDC_SetWindowPosition(&LtdcHandle, bottomStartBot, leftStartBot, 0);
483 HAL_LTDC_SetAddress(&LtdcHandle, pBot, 0); 499 HAL_LTDC_SetAddress(&LtdcHandle, pBot, 0);
484 HAL_LTDC_SetAlpha(&LtdcHandle, 255, 0); 500 HAL_LTDC_SetAlpha(&LtdcHandle, 255, 0);
485 FrameHandler.actualBottom.height = heightBot; 501 FrameHandler.actualBottom.height = heightBot;
505 { 521 {
506 logoStatus +=20; 522 logoStatus +=20;
507 HAL_LTDC_SetAlpha(&LtdcHandle, logoStatus-55, 1); 523 HAL_LTDC_SetAlpha(&LtdcHandle, logoStatus-55, 1);
508 HAL_LTDC_SetAlpha(&LtdcHandle, 255+55-logoStatus, 0); 524 HAL_LTDC_SetAlpha(&LtdcHandle, 255+55-logoStatus, 0);
509 } 525 }
526 FrameHandler.NextBottomRead = nextBottomBackup;
510 break; 527 break;
511 } 528 }
512 return; 529 return;
513 } 530 }
514 else if (backgroundHwStatus != LOGOOFF) 531 else if (backgroundHwStatus != LOGOOFF)
519 HAL_LTDC_ConfigCLUT(&LtdcHandle, (uint32_t *)indexHWcolor, indexHWcolorSIZE, 0); 536 HAL_LTDC_ConfigCLUT(&LtdcHandle, (uint32_t *)indexHWcolor, indexHWcolorSIZE, 0);
520 HAL_LTDC_SetAddress(&LtdcHandle, pBackgroundHwFrame, 0); 537 HAL_LTDC_SetAddress(&LtdcHandle, pBackgroundHwFrame, 0);
521 HAL_LTDC_SetWindowSize(&LtdcHandle, 480, 800, 0); 538 HAL_LTDC_SetWindowSize(&LtdcHandle, 480, 800, 0);
522 HAL_LTDC_SetWindowPosition(&LtdcHandle, 0, 0, 0); 539 HAL_LTDC_SetWindowPosition(&LtdcHandle, 0, 0, 0);
523 backgroundHwStatus = 2; 540 backgroundHwStatus = 2;
541 FrameHandler.NextBottomRead = nextBottomBackup;
524 break; 542 break;
525 543
526 case LOGOSTOP: 544 case LOGOSTOP:
527 HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, 0); 545 HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, 0);
528 pBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].pBuffer; 546 pBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].pBuffer;
529 heightBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].height; 547 heightBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].height;
530 widthBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].width; 548 widthBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].width;
531 leftStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].leftStart; 549 leftStartBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].leftStart;
532 bottomStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].bottomStart; 550 bottomStartBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].bottomStart;
533 HAL_LTDC_SetWindowSize(&LtdcHandle, heightBot, widthBot, 0); 551 HAL_LTDC_SetWindowSize(&LtdcHandle, heightBot, widthBot, 0);
534 HAL_LTDC_SetWindowPosition(&LtdcHandle, bottomStartBot, leftStartBot, 0); 552 HAL_LTDC_SetWindowPosition(&LtdcHandle, bottomStartBot, leftStartBot, 0);
535 HAL_LTDC_SetAddress(&LtdcHandle, pBot, 0); 553 HAL_LTDC_SetAddress(&LtdcHandle, pBot, 0);
536 HAL_LTDC_SetAlpha(&LtdcHandle, 255, 0); 554 HAL_LTDC_SetAlpha(&LtdcHandle, 255, 0);
537 FrameHandler.actualBottom.height = heightBot; 555 FrameHandler.actualBottom.height = heightBot;
541 FrameHandler.actualBottom.pBuffer = pBot; 559 FrameHandler.actualBottom.pBuffer = pBot;
542 backgroundHwStatus = LOGOOFF; 560 backgroundHwStatus = LOGOOFF;
543 break; 561 break;
544 562
545 default: 563 default:
564 FrameHandler.NextBottomRead = nextBottomBackup;
546 break; 565 break;
547 } 566 }
548 return; 567 return;
549 } 568 }
550 else 569 else
551 { 570 {
552 pBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].pBuffer; 571 pBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].pBuffer;
553 heightBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].height; 572 heightBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].height;
554 widthBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].width; 573 widthBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].width;
555 leftStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].leftStart; 574 leftStartBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].leftStart;
556 bottomStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].bottomStart; 575 bottomStartBot = FrameHandler.nextBottom[FrameHandler.NextBottomRead].bottomStart;
557 576
558 if(FrameHandler.actualBottom.pBuffer == pBot) 577 if(FrameHandler.actualBottom.pBuffer == pBot)
559 pBot = 0; 578 pBot = 0;
560 579
561 if((FrameHandler.actualBottom.height != heightBot) || (FrameHandler.actualBottom.width != widthBot)) 580 if((FrameHandler.actualBottom.height != heightBot) || (FrameHandler.actualBottom.width != widthBot))
3143 if((*(char*)pText == '\005') || (*(char*)pText == '\006')) 3162 if((*(char*)pText == '\005') || (*(char*)pText == '\006'))
3144 { 3163 {
3145 Xsum += 45; 3164 Xsum += 45;
3146 } 3165 }
3147 else 3166 else
3148 if((*(char*)pText) & 0x80) /* Identify a UNICODE character other than standard ASCII using the highest bit */ 3167 {
3149 { 3168 if((*(char*)pText) & 0x80) /* Identify a UNICODE character other than standard ASCII using the highest bit */
3150 decodeUTF8 = ((*(char*)pText) & 0x1F) << 6; /* use 5bits of first byte for upper part of unicode */ 3169 {
3151 pText++; 3170 decodeUTF8 = ((*(char*)pText) & 0x1F) << 6; /* use 5bits of first byte for upper part of unicode */
3152 decodeUTF8 |= (*(char*)pText) & 0x3F; /* add lower 6bits as second part of the unicode */ 3171 pText++;
3153 } 3172 decodeUTF8 |= (*(char*)pText) & 0x3F; /* add lower 6bits as second part of the unicode */
3154 else 3173 }
3155 { 3174 else
3156 decodeUTF8 = *(char*)pText; /* place ASCII char */ 3175 {
3157 } 3176 decodeUTF8 = *(char*)pText; /* place ASCII char */
3158 3177 }
3159 Xsum += GFX_Character_Width(decodeUTF8, ptargetFont); 3178 Xsum += GFX_Character_Width(decodeUTF8, ptargetFont);
3179 }
3160 3180
3161 pText++; 3181 pText++;
3162 j++; 3182 j++;
3163 if((ptargetFont == &FontT144) && (*(char*)pText != 0)) 3183 if((ptargetFont == &FontT144) && (*(char*)pText != 0))
3164 Xsum += 3; 3184 Xsum += 3;
3500 uint8_t i; 3520 uint8_t i;
3501 uint8_t retVal = 1; 3521 uint8_t retVal = 1;
3502 3522
3503 if(DMA2D_at_work == 255) 3523 if(DMA2D_at_work == 255)
3504 { 3524 {
3505 /* new for debug hw 151202 */
3506 for(i=1;i<MAXFRAMECOUNTER;i++)
3507 {
3508 frameCounter[i] = 0;
3509 }
3510 for(int i=1;i<MAXFRAMES;i++)
3511 {
3512 if(frame[i].status == BLOCKED)
3513 {
3514 if(frame[i].caller < (MAXFRAMECOUNTER - 2))
3515 frameCounter[frame[i].caller]++;
3516 else
3517 frameCounter[MAXFRAMECOUNTER-3]++;
3518 }
3519 else
3520 if(frame[i].status == RELEASED)
3521 frameCounter[MAXFRAMECOUNTER-2]++;
3522 else
3523 frameCounter[MAXFRAMECOUNTER-1]++;
3524 }
3525
3526 i = 0; 3525 i = 0;
3527 /* skip frame cleaning for actual frames which have not yet been replaced by new top/bottom frames */ 3526 /* skip frame cleaning for actual frames which have not yet been replaced by new top/bottom frames */
3528 while((i < MAXFRAMES) && ((frame[i].status != RELEASED) || (frame[i].StartAddress == GFX_get_pActualFrameTop()) || (frame[i].StartAddress == GFX_get_pActualFrameBottom()))) 3527 while((i < MAXFRAMES) && ((frame[i].status != RELEASED) || (frame[i].StartAddress == GFX_get_pActualFrameTop()) || (frame[i].StartAddress == GFX_get_pActualFrameBottom())))
3529 i++; 3528 i++;
3530 3529