Mercurial > public > ostc4
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 |