Mercurial > public > ostc4
comparison BootLoader/Src/gfx_engine_mini.c @ 1016:0dd92e9b70a2 BootloaderOstc5
Bootloader use compressed fonts:
The previous Bootloader was larger than 128k => not fitting into the first sectors of the second flash bank. Most memory is occupied by the two fonts in use. In order to make the bootloader small enough for the bootloader update function the fonts need to be compressed. To avoid code changes in visualization functions the compressed fonts are decompressed into RAM and then used in the same way as before.
| author | Ideenmodellierer |
|---|---|
| date | Wed, 28 May 2025 17:20:44 +0200 |
| parents | 23e94766d00a |
| children | 493a5903ec20 |
comparison
equal
deleted
inserted
replaced
| 1015:4ef0511c6665 | 1016:0dd92e9b70a2 |
|---|---|
| 173 | 173 |
| 174 /* Private function prototypes -----------------------------------------------*/ | 174 /* Private function prototypes -----------------------------------------------*/ |
| 175 | 175 |
| 176 static uint32_t GFX_write_char(GFX_DrawCfgWindow* hgfx, GFX_CfgWriteString* cfg, uint8_t character, tFont *Font); | 176 static uint32_t GFX_write_char(GFX_DrawCfgWindow* hgfx, GFX_CfgWriteString* cfg, uint8_t character, tFont *Font); |
| 177 static uint32_t GFX_write_substring(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, uint8_t textId, int8_t nextCharFor2Byte); | 177 static uint32_t GFX_write_substring(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, uint8_t textId, int8_t nextCharFor2Byte); |
| 178 static uint32_t GFX_write__Modify_Xdelta__Centered(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, const char *pText); | |
| 179 static uint32_t GFX_write__Modify_Xdelta__RightAlign(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, const char *pTextInput); | |
| 180 static void GFX_Error_Handler(void); | 178 static void GFX_Error_Handler(void); |
| 181 static void GFX_Dma2d_TransferComplete(DMA2D_HandleTypeDef* Dma2dHandle); | 179 static void GFX_Dma2d_TransferComplete(DMA2D_HandleTypeDef* Dma2dHandle); |
| 182 static void GFX_Dma2d_TransferError(DMA2D_HandleTypeDef* Dma2dHandle); | 180 static void GFX_Dma2d_TransferError(DMA2D_HandleTypeDef* Dma2dHandle); |
| 183 static void GFX_clear_frame_dma2d(uint8_t frameId); | 181 static void GFX_clear_frame_dma2d(uint8_t frameId); |
| 184 | 182 |
| 282 | 280 |
| 283 write_content_simple(&tLogoTemp, 0, 800, 240-24, &FontT24,localtext,CLUT_Font020); | 281 write_content_simple(&tLogoTemp, 0, 800, 240-24, &FontT24,localtext,CLUT_Font020); |
| 284 */ | 282 */ |
| 285 } | 283 } |
| 286 | 284 |
| 285 void decompressFont(const tFont* pFont, const tImageComp** pFontComp) | |
| 286 { | |
| 287 uint16_t indexFont = 0; | |
| 288 uint16_t indexData = 0; | |
| 289 uint8_t data = 0; | |
| 290 uint8_t count = 0; | |
| 291 uint8_t targetIndex = 0; | |
| 292 uint8_t* pPixel; | |
| 293 | |
| 294 for (indexFont = 0; indexFont < pFont->length; indexFont++) | |
| 295 { | |
| 296 pPixel = (uint8_t*)pFont->chars[indexFont].image->data; | |
| 297 for(indexData = 0; indexData < pFontComp[indexFont]->sizeComp; indexData += 2) | |
| 298 { | |
| 299 data = pFontComp[indexFont]->dataComp[indexData]; | |
| 300 count = pFontComp[indexFont]->dataComp[indexData + 1]; | |
| 301 for (targetIndex = 0; targetIndex < count; targetIndex++) | |
| 302 { | |
| 303 *pPixel++ = data; | |
| 304 } | |
| 305 } | |
| 306 } | |
| 307 } | |
| 287 | 308 |
| 288 void GFX_build_logo_frame(void) | 309 void GFX_build_logo_frame(void) |
| 289 { | 310 { |
| 290 GFX_DrawCfgScreen tLogoTemp; | 311 GFX_DrawCfgScreen tLogoTemp; |
| 291 SWindowGimpStyle windowGimp; | 312 SWindowGimpStyle windowGimp; |
| 1654 if((*pText) == TXT_MINIMAL) // for customtext and anything with Sonderzeichen | 1675 if((*pText) == TXT_MINIMAL) // for customtext and anything with Sonderzeichen |
| 1655 minimal = 1; | 1676 minimal = 1; |
| 1656 else | 1677 else |
| 1657 minimal = 0; | 1678 minimal = 0; |
| 1658 | 1679 |
| 1659 if(Font == &FontT48) | 1680 if(Font == &FontT48min) |
| 1660 { | 1681 { |
| 1661 settings.TinyFont = (uint32_t)&FontT24; | 1682 settings.TinyFont = (uint32_t)&FontT24min; |
| 1662 settings.TinyFontExtraYdelta = 6; | 1683 settings.TinyFontExtraYdelta = 6; |
| 1663 } | 1684 } |
| 1664 | 1685 |
| 1665 settings.actualFont = (tFont *)settings.font; | 1686 settings.actualFont = (tFont *)settings.font; |
| 1666 | 1687 |
| 1686 if((*pText == '\t') && !minimal) | 1707 if((*pText == '\t') && !minimal) |
| 1687 settings.Xdelta = hgfx->WindowTab - hgfx->WindowX0; | 1708 settings.Xdelta = hgfx->WindowTab - hgfx->WindowX0; |
| 1688 else | 1709 else |
| 1689 if(*pText == '\r') // carriage return, no newline | 1710 if(*pText == '\r') // carriage return, no newline |
| 1690 settings.Xdelta = 0; | 1711 settings.Xdelta = 0; |
| 1691 else | |
| 1692 if((*pText == '\001')) // center | |
| 1693 settings.Xdelta = GFX_write__Modify_Xdelta__Centered(&settings, hgfx, pText+1); | |
| 1694 else | |
| 1695 if((*pText == '\002')) // right | |
| 1696 settings.Xdelta = GFX_write__Modify_Xdelta__RightAlign(&settings, hgfx, pText+1); | |
| 1697 else | 1712 else |
| 1698 if((*pText == '\003') && !minimal) // doubleSize | 1713 if((*pText == '\003') && !minimal) // doubleSize |
| 1699 settings.doubleSize = 1; | 1714 settings.doubleSize = 1; |
| 1700 else | 1715 else |
| 1701 /* Xdelta -up/down changes */ | 1716 /* Xdelta -up/down changes */ |
| 2510 return 0x0000FFFF; | 2525 return 0x0000FFFF; |
| 2511 else | 2526 else |
| 2512 return cfg->Xdelta + width; | 2527 return cfg->Xdelta + width; |
| 2513 } | 2528 } |
| 2514 | 2529 |
| 2515 /** | |
| 2516 ****************************************************************************** | |
| 2517 * @brief GFX write Modify Ydelta for align. / calc Ydelta for start | |
| 2518 * @author heinrichs weikamp gmbh | |
| 2519 * @version V0.0.1 | |
| 2520 * @date 22-April-2014 | |
| 2521 ****************************************************************************** | |
| 2522 * | |
| 2523 * @param *hgfx: check gfx_engine.h. | |
| 2524 * @param *cfg: Ydelta, Font | |
| 2525 * @param *pText: character | |
| 2526 * @retval Ydelta: 0 if text has to start left ( and probably does not fit) | |
| 2527 */ | |
| 2528 | |
| 2529 static uint32_t GFX_write__Modify_Xdelta__Centered(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, const char *pTextInput) | |
| 2530 { | |
| 2531 char cText[101]; | |
| 2532 uint32_t result; | |
| 2533 uint32_t Xsum; | |
| 2534 uint32_t j; | |
| 2535 uint32_t pText; | |
| 2536 uint16_t decodeUTF8; | |
| 2537 uint8_t tinyState = 0; /* used to identify the usage of tiny font */ | |
| 2538 tFont* ptargetFont; | |
| 2539 | |
| 2540 pText = (uint32_t)&cText[0]; | |
| 2541 Xsum = 0; | |
| 2542 j = 0; | |
| 2543 ptargetFont = (tFont *)cfg->font; | |
| 2544 while (*(char*)pText != 0)// und fehlend: Abfrage window / image size | |
| 2545 { | |
| 2546 if(*(char*)pText == '\016') /* request font change */ | |
| 2547 { | |
| 2548 tinyState++; | |
| 2549 } | |
| 2550 if(*(char*)pText == '\017') /* request font reset */ | |
| 2551 { | |
| 2552 tinyState = 0; | |
| 2553 } | |
| 2554 | |
| 2555 if(tinyState > 1) | |
| 2556 { | |
| 2557 ptargetFont = (tFont *)cfg->TinyFont; | |
| 2558 } | |
| 2559 else | |
| 2560 { | |
| 2561 ptargetFont = (tFont *)cfg->font; | |
| 2562 } | |
| 2563 | |
| 2564 decodeUTF8 = *(char*)pText; /* place ASCII char */ | |
| 2565 if((*(char*)pText == '\005') || (*(char*)pText == '\006')) | |
| 2566 { | |
| 2567 Xsum += 45; | |
| 2568 } | |
| 2569 else | |
| 2570 { | |
| 2571 if((*(char*)pText) & 0x80) /* Identify a UNICODE character other than standard ASCII using the highest bit */ | |
| 2572 { | |
| 2573 decodeUTF8 = ((*(char*)pText) & 0x1F) << 6; /* use 5bits of first byte for upper part of unicode */ | |
| 2574 pText++; | |
| 2575 decodeUTF8 |= (*(char*)pText) & 0x3F; /* add lower 6bits as second part of the unicode */ | |
| 2576 } | |
| 2577 else | |
| 2578 { | |
| 2579 decodeUTF8 = *(char*)pText; /* place ASCII char */ | |
| 2580 } | |
| 2581 Xsum += GFX_Character_Width(decodeUTF8, ptargetFont); | |
| 2582 } | |
| 2583 | |
| 2584 pText++; | |
| 2585 j++; | |
| 2586 } | |
| 2587 pText -= j; | |
| 2588 | |
| 2589 if(cfg->doubleSize) | |
| 2590 Xsum *= 2; | |
| 2591 | |
| 2592 result = hgfx->WindowX1 - hgfx->WindowX0; | |
| 2593 if(Xsum < result) | |
| 2594 { | |
| 2595 result -= Xsum; | |
| 2596 result /= 2; | |
| 2597 } | |
| 2598 else | |
| 2599 result = 0; | |
| 2600 return result; | |
| 2601 } | |
| 2602 | |
| 2603 | |
| 2604 static uint32_t GFX_write__Modify_Xdelta__RightAlign(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, const char *pTextInput) | |
| 2605 { | |
| 2606 uint32_t result; | |
| 2607 uint32_t Xsum; | |
| 2608 uint32_t j; | |
| 2609 tFont *font; | |
| 2610 char cText[101]; | |
| 2611 uint32_t pText; | |
| 2612 uint16_t decodeUTF8; | |
| 2613 uint8_t tinyState = 0; /* used to identify the usage of tiny font */ | |
| 2614 | |
| 2615 cText[0] = 0; | |
| 2616 | |
| 2617 // ----------------------------- | |
| 2618 pText = (uint32_t)&cText[0]; | |
| 2619 // ----------------------------- | |
| 2620 | |
| 2621 font = (tFont *)cfg->font; | |
| 2622 Xsum = 0; | |
| 2623 j = 0; | |
| 2624 | |
| 2625 while (*(char*)pText != 0)// und fehlend: Abfrage window / image size | |
| 2626 { | |
| 2627 if(*(char*)pText == '\016') /* request font change */ | |
| 2628 { | |
| 2629 tinyState++; | |
| 2630 } | |
| 2631 if(*(char*)pText == '\017') /* request font reset */ | |
| 2632 { | |
| 2633 tinyState = 0; | |
| 2634 } | |
| 2635 | |
| 2636 if(tinyState > 1) | |
| 2637 { | |
| 2638 font = (tFont *)cfg->TinyFont; | |
| 2639 } | |
| 2640 else | |
| 2641 { | |
| 2642 font = (tFont *)cfg->font; | |
| 2643 } | |
| 2644 | |
| 2645 if(*(char*)pText == ' ') | |
| 2646 { | |
| 2647 Xsum += font->spacesize; | |
| 2648 } | |
| 2649 else | |
| 2650 if((*(char*)pText == '\005') || (*(char*)pText == '\006')) | |
| 2651 { | |
| 2652 Xsum += 45; | |
| 2653 } | |
| 2654 else | |
| 2655 { | |
| 2656 if((*(char*)pText) & 0x80) /* Identify a UNICODE character other than standard ASCII using the highest bit */ | |
| 2657 { | |
| 2658 decodeUTF8 = ((*(char*)pText) & 0x1F) << 6; /* use 5bits of first byte for upper part of unicode */ | |
| 2659 pText++; | |
| 2660 decodeUTF8 |= (*(char*)pText) & 0x3F; /* add lower 6bits as second part of the unicode */ | |
| 2661 } | |
| 2662 else | |
| 2663 { | |
| 2664 decodeUTF8 = *(char*)pText; | |
| 2665 } | |
| 2666 Xsum += GFX_Character_Width(decodeUTF8, font); /* lookup character and add width */ | |
| 2667 } | |
| 2668 pText++; | |
| 2669 j++; | |
| 2670 } | |
| 2671 pText -= j; | |
| 2672 | |
| 2673 if(cfg->doubleSize) | |
| 2674 Xsum *= 2; | |
| 2675 | |
| 2676 result = hgfx->WindowX1 - hgfx->WindowX0 - 1; | |
| 2677 if(Xsum < result) | |
| 2678 result -= Xsum; | |
| 2679 else | |
| 2680 result = 0; | |
| 2681 | |
| 2682 return result; | |
| 2683 } | |
| 2684 | |
| 2685 void GFX_LTDC_Init(void) | 2530 void GFX_LTDC_Init(void) |
| 2686 { | 2531 { |
| 2687 GFX_LTDC_Init_display1(); | 2532 GFX_LTDC_Init_display1(); |
| 2688 } | 2533 } |
| 2689 | 2534 |
| 2973 | 2818 |
| 2974 | 2819 |
| 2975 void gfx_write_topline_simple(GFX_DrawCfgScreen *tMscreen, const char *text, uint8_t color) | 2820 void gfx_write_topline_simple(GFX_DrawCfgScreen *tMscreen, const char *text, uint8_t color) |
| 2976 { | 2821 { |
| 2977 GFX_DrawCfgWindow hgfx; | 2822 GFX_DrawCfgWindow hgfx; |
| 2978 const tFont *Font = &FontT48; | 2823 const tFont *Font = &FontT48min; |
| 2979 | 2824 |
| 2980 hgfx.Image = tMscreen; | 2825 hgfx.Image = tMscreen; |
| 2981 hgfx.WindowNumberOfTextLines = 1; | 2826 hgfx.WindowNumberOfTextLines = 1; |
| 2982 hgfx.WindowLineSpacing = 0; | 2827 hgfx.WindowLineSpacing = 0; |
| 2983 | 2828 |
| 2992 | 2837 |
| 2993 | 2838 |
| 2994 void gfx_write_page_number(GFX_DrawCfgScreen *tMscreen, uint8_t page, uint8_t total, uint8_t color) | 2839 void gfx_write_page_number(GFX_DrawCfgScreen *tMscreen, uint8_t page, uint8_t total, uint8_t color) |
| 2995 { | 2840 { |
| 2996 GFX_DrawCfgWindow hgfx; | 2841 GFX_DrawCfgWindow hgfx; |
| 2997 const tFont *Font = &FontT48; | 2842 const tFont *Font = &FontT48min; |
| 2998 char text[7]; | 2843 char text[7]; |
| 2999 uint8_t i, secondDigitPage, secondDigitTotal; | 2844 uint8_t i, secondDigitPage, secondDigitTotal; |
| 3000 | 2845 |
| 3001 if(total > 8) | 2846 if(total > 8) |
| 3002 { | 2847 { |
| 3003 Font = &FontT24; | 2848 Font = &FontT24min; |
| 3004 } | 2849 } |
| 3005 | 2850 |
| 3006 hgfx.Image = tMscreen; | 2851 hgfx.Image = tMscreen; |
| 3007 hgfx.WindowNumberOfTextLines = 1; | 2852 hgfx.WindowNumberOfTextLines = 1; |
| 3008 hgfx.WindowLineSpacing = 0; | 2853 hgfx.WindowLineSpacing = 0; |
| 3009 hgfx.WindowTab = 0; | 2854 hgfx.WindowTab = 0; |
| 3010 | 2855 |
| 3011 hgfx.WindowX1 = 779; | 2856 hgfx.WindowX1 = 779; |
| 3012 if(Font == &FontT24) | 2857 if(Font == &FontT24min) |
| 3013 { | 2858 { |
| 3014 hgfx.WindowX0 = hgfx.WindowX1 - (Font->spacesize*3); | 2859 hgfx.WindowX0 = hgfx.WindowX1 - (Font->spacesize*3); |
| 3015 } | 2860 } |
| 3016 else | 2861 else |
| 3017 { | 2862 { |
