From 82dce3ee601049cf548ff4518902ab8e8fa62a0b Mon Sep 17 00:00:00 2001 From: Damjan Adamic Date: Thu, 5 Jan 2017 21:44:59 +0100 Subject: [PATCH] Projectkk2glider/flash savings (#4199) * Flash savings: getFileExtension() de-templated, saves 160 bytes * Flash savings: several variables moved to rodata, RGB macro optimization (speed and can now be used to initialize rodata) Result for Horus: text data bss dec 1261182 808603 42020 2111805 before 1267149 803335 42124 2112608 after (data size also counts .sram section) 5kB saved in .data section (RAM and FLASH) * Removed compiler warnings * RGB() and ARGB() gtests added * ARGB() optimized --- radio/src/crc16.cpp | 2 +- radio/src/debug.cpp | 6 +-- radio/src/debug.h | 4 +- radio/src/gui/480x272/colors.h | 8 ++- radio/src/gui/480x272/fonts.cpp | 28 +++++----- radio/src/gui/480x272/radio_sdmanager.cpp | 6 +-- radio/src/gui/480x272/widget.h | 4 +- radio/src/gui/480x272/widgets/text.cpp | 2 +- .../src/gui/common/stdlcd/radio_sdmanager.cpp | 6 +-- radio/src/lua/interface.cpp | 6 +-- radio/src/sdcard.cpp | 32 +++++++++-- radio/src/sdcard.h | 27 +--------- radio/src/tests/colorlcd.cpp | 54 +++++++++++++++++++ .../src/stm32f4xx_rcc.c | 2 +- 14 files changed, 120 insertions(+), 67 deletions(-) create mode 100644 radio/src/tests/colorlcd.cpp diff --git a/radio/src/crc16.cpp b/radio/src/crc16.cpp index 56319e271..bd4db574e 100644 --- a/radio/src/crc16.cpp +++ b/radio/src/crc16.cpp @@ -66,7 +66,7 @@ uint16_t crc16(const uint8_t * buf, uint32_t len) } // CRC8 implementation with polynom = x^8+x^7+x^6+x^4+x^2+1 (0xD5) -unsigned char crc8tab[256] = { +const unsigned char crc8tab[256] = { 0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54, 0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D, 0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06, diff --git a/radio/src/debug.cpp b/radio/src/debug.cpp index d67f0431b..de15ce0e6 100644 --- a/radio/src/debug.cpp +++ b/radio/src/debug.cpp @@ -106,7 +106,7 @@ void dumpTraceBuffer() #if defined(DEBUG_INTERRUPTS) #if defined(PCBHORUS) - const char * interruptNames[INT_LAST] = { + const char * const interruptNames[INT_LAST] = { "Tick ", // INT_TICK, "1ms ", // INT_1MS, "Ser2 ", // INT_SER2, @@ -139,7 +139,7 @@ void dumpTraceBuffer() #endif // #if defined(DEBUG_USB_INTERRUPTS) }; #elif defined(PCBTARANIS) - const char * interruptNames[INT_LAST] = { + const char * const interruptNames[INT_LAST] = { "Tick ", // INT_TICK, "5ms ", // INT_5MS, "Audio", // INT_AUDIO, @@ -231,7 +231,7 @@ void DebugTimer::stop() DebugTimer debugTimers[DEBUG_TIMERS_COUNT]; -const char * debugTimerNames[DEBUG_TIMERS_COUNT] = { +const char * const debugTimerNames[DEBUG_TIMERS_COUNT] = { "Pulses int." // debugTimerIntPulses, ,"Pulses dur." // debugTimerIntPulsesDuration, ,"10ms dur. " // debugTimerPer10ms, diff --git a/radio/src/debug.h b/radio/src/debug.h index 7a0982c26..821df2cd2 100644 --- a/radio/src/debug.h +++ b/radio/src/debug.h @@ -273,7 +273,7 @@ struct InterruptCounters uint32_t resetTime; }; -extern const char * interruptNames[INT_LAST]; +extern const char * const interruptNames[INT_LAST]; extern struct InterruptCounters interruptCounters; #define DEBUG_INTERRUPT(int) (++interruptCounters.cnt[int]) @@ -388,7 +388,7 @@ enum DebugTimers { }; extern DebugTimer debugTimers[DEBUG_TIMERS_COUNT]; -extern const char * debugTimerNames[DEBUG_TIMERS_COUNT]; +extern const char * const debugTimerNames[DEBUG_TIMERS_COUNT]; #endif // #if defined(__cplusplus) diff --git a/radio/src/gui/480x272/colors.h b/radio/src/gui/480x272/colors.h index 0a4611143..5d5bf8131 100644 --- a/radio/src/gui/480x272/colors.h +++ b/radio/src/gui/480x272/colors.h @@ -25,11 +25,9 @@ #undef OPAQUE #undef RGB -#define TO4BITS(x) (uint32_t(limit(0, x, 255)) >> 4) -#define TO5BITS(x) (uint32_t(limit(0, x, 255)) >> 3) -#define TO6BITS(x) (uint32_t(limit(0, x, 255)) >> 2) -#define RGB(r, g, b) ((TO5BITS(r) << 11) + (TO6BITS(g) << 5) + (TO5BITS(b) << 0)) -#define ARGB(a, r, g, b) ((TO4BITS(a) << 12) + (TO4BITS(r) << 8) + (TO4BITS(g) << 4) + (TO4BITS(b) << 0)) +#define RGB(r, g, b) (uint16_t)((((r) & 0xF8) << 8) + (((g) & 0xFC) << 3) + (((b) & 0xF8) >> 3)) +#define ARGB(a, r, g, b) (uint16_t)((((a) & 0xF0) << 8) + (((r) & 0xF0) << 4) + (((g) & 0xF0) << 0) + (((b) & 0xF0) >> 4)) + #define WHITE RGB(0xFF, 0xFF, 0xFF) #define BLACK RGB(0, 0, 0) #define YELLOW RGB(0xF0, 0xD0, 0x10) diff --git a/radio/src/gui/480x272/fonts.cpp b/radio/src/gui/480x272/fonts.cpp index d00a8445e..592f1f14b 100644 --- a/radio/src/gui/480x272/fonts.cpp +++ b/radio/src/gui/480x272/fonts.cpp @@ -20,59 +20,59 @@ #include "opentx.h" -uint16_t font_tinsize_specs[] = { +const uint16_t font_tinsize_specs[] = { #include "font_tinsize.specs" }; -pm_uchar font_tinsize[] = { +const pm_uchar font_tinsize[] = { #include "font_tinsize.lbm" }; -uint16_t font_smlsize_specs[] = { +const uint16_t font_smlsize_specs[] = { #include "font_smlsize.specs" }; -pm_uchar font_smlsize[] = { +const pm_uchar font_smlsize[] = { #include "font_smlsize.lbm" }; -uint16_t font_stdsize_specs[] = { +const uint16_t font_stdsize_specs[] = { #include "font_stdsize.specs" }; -pm_uchar font_stdsize[] = { +const pm_uchar font_stdsize[] = { #include "font_stdsize.lbm" }; -uint16_t font_midsize_specs[] = { +const uint16_t font_midsize_specs[] = { #include "font_midsize.specs" }; -pm_uchar font_midsize[] = { +const pm_uchar font_midsize[] = { #include "font_midsize.lbm" }; -uint16_t font_dblsize_specs[] = { +const uint16_t font_dblsize_specs[] = { #include "font_dblsize.specs" }; -pm_uchar font_dblsize[] = { +const pm_uchar font_dblsize[] = { #include "font_dblsize.lbm" }; -uint16_t font_xxlsize_specs[] = { +const uint16_t font_xxlsize_specs[] = { #include "font_xxlsize.specs" }; -pm_uchar font_xxlsize[] = { +const pm_uchar font_xxlsize[] = { #include "font_xxlsize.lbm" }; -uint16_t font_stdsizebold_specs[] = { +const uint16_t font_stdsizebold_specs[] = { #include "font_stdsizebold.specs" }; -pm_uchar font_stdsizebold[] = { +const pm_uchar font_stdsizebold[] = { #include "font_stdsizebold.lbm" }; diff --git a/radio/src/gui/480x272/radio_sdmanager.cpp b/radio/src/gui/480x272/radio_sdmanager.cpp index 794e0d7ad..e28457e7c 100644 --- a/radio/src/gui/480x272/radio_sdmanager.cpp +++ b/radio/src/gui/480x272/radio_sdmanager.cpp @@ -216,7 +216,7 @@ bool menuRadioSdManager(event_t _event) if (!strcmp(line, "..")) { break; // no menu for parent dir } - char * ext = getFileExtension(line); + const char * ext = getFileExtension(line); if (ext) { if (!strcasecmp(ext, SOUNDS_EXT)) { POPUP_MENU_ADD_ITEM(STR_PLAY_FILE); @@ -337,7 +337,7 @@ bool menuRadioSdManager(event_t _event) if (reusableBuffer.sdmanager.lines[i][0]) { if (s_editMode == EDIT_MODIFY_STRING && attr) { uint8_t extlen, efflen; - char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen); + const char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen); editName(MENUS_MARGIN_LEFT, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen, _event, attr, 0); efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen); if (s_editMode == 0) { @@ -366,7 +366,7 @@ bool menuRadioSdManager(event_t _event) } } - char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]); + const char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]); if (ext && isExtensionMatching(ext, BITMAPS_EXT)) { if (currentBitmapIndex != menuVerticalPosition) { currentBitmapIndex = menuVerticalPosition; diff --git a/radio/src/gui/480x272/widget.h b/radio/src/gui/480x272/widget.h index ea4c7fa78..52807428e 100644 --- a/radio/src/gui/480x272/widget.h +++ b/radio/src/gui/480x272/widget.h @@ -45,12 +45,12 @@ union ZoneOptionValue #define OPTION_VALUE_UNSIGNED(x) uint32_t(x) #define OPTION_VALUE_SIGNED(x) uint32_t(x) #define OPTION_VALUE_BOOL(x) uint32_t(x) - #define OPTION_VALUE_STRING(...) *(ZoneOptionValue *)(const char *)__VA_ARGS__ + #define OPTION_VALUE_STRING(...) { .stringValue = {__VA_ARGS__} } #else #define OPTION_VALUE_UNSIGNED(x) { .unsignedValue = (x) } #define OPTION_VALUE_SIGNED(x) { .signedValue = (x) } #define OPTION_VALUE_BOOL(x) { .boolValue = (x) } - #define OPTION_VALUE_STRING(...) *(ZoneOptionValue *)(const char *)__VA_ARGS__ + #define OPTION_VALUE_STRING(...) { .stringValue = {__VA_ARGS__} } #endif struct ZoneOption diff --git a/radio/src/gui/480x272/widgets/text.cpp b/radio/src/gui/480x272/widgets/text.cpp index 5a84c41d1..e35085839 100644 --- a/radio/src/gui/480x272/widgets/text.cpp +++ b/radio/src/gui/480x272/widgets/text.cpp @@ -34,7 +34,7 @@ class TextWidget: public Widget }; const ZoneOption TextWidget::options[] = { - { "Text", ZoneOption::String, OPTION_VALUE_STRING("\015\347\0\14\377\376\373\364") }, + { "Text", ZoneOption::String, OPTION_VALUE_STRING('\15', '\347', '\0', '\14', '\377', '\376', '\373', '\364') }, { "Color", ZoneOption::Color, OPTION_VALUE_UNSIGNED(RED) }, { "Size", ZoneOption::TextSize, OPTION_VALUE_UNSIGNED(0) }, { NULL, ZoneOption::Bool } diff --git a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp index a333c7af9..e62b15948 100644 --- a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp +++ b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp @@ -258,7 +258,7 @@ void menuRadioSdManager(event_t _event) break; // no menu for parent dir } #if defined(CPUARM) - char * ext = getFileExtension(line); + const char * ext = getFileExtension(line); if (ext) { if (!strcasecmp(ext, SOUNDS_EXT)) { POPUP_MENU_ADD_ITEM(STR_PLAY_FILE); @@ -401,7 +401,7 @@ void menuRadioSdManager(event_t _event) #if defined(CPUARM) if (s_editMode == EDIT_MODIFY_STRING && attr) { uint8_t extlen, efflen; - char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen); + const char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen); editName(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen, _event, attr, 0); efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen); if (s_editMode == 0) { @@ -428,7 +428,7 @@ void menuRadioSdManager(event_t _event) } #if LCD_DEPTH > 1 - char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]); + const char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]); if (ext && isExtensionMatching(ext, BITMAPS_EXT)) { if (lastPos != menuVerticalPosition) { if (!lcdLoadBitmap(modelBitmap, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) { diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index e4950c1b9..59f52cbd8 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -38,9 +38,9 @@ extern "C" { lua_State *lsScripts = NULL; uint8_t luaState = 0; uint8_t luaScriptsCount = 0; -ScriptInternalData scriptInternalData[MAX_SCRIPTS] = { { SCRIPT_NOFILE, 0 } }; -ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS] = { {0} }; -ScriptInternalData standaloneScript = { SCRIPT_NOFILE, 0 }; +ScriptInternalData scriptInternalData[MAX_SCRIPTS]; +ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS]; +ScriptInternalData standaloneScript; uint16_t maxLuaInterval = 0; uint16_t maxLuaDuration = 0; bool luaLcdAllowed; diff --git a/radio/src/sdcard.cpp b/radio/src/sdcard.cpp index 24217cb40..3d5ffd676 100644 --- a/radio/src/sdcard.cpp +++ b/radio/src/sdcard.cpp @@ -114,7 +114,7 @@ bool isFilePatternAvailable(const char * path, const char * file, const char * p char * getFileIndex(char * filename, unsigned int & value) { value = 0; - char * pos = getFileExtension(filename); + char * pos = (char *)getFileExtension(filename); if (!pos || pos == filename) return NULL; int multiplier = 1; @@ -148,7 +148,7 @@ int findNextFileIndex(char * filename, uint8_t size, const char * directory) uint8_t extlen; char * indexPos = getFileIndex(filename, index); char extension[LEN_FILE_EXTENSION_MAX+1] = "\0"; - char *p = getFileExtension(filename, 0, 0, NULL, &extlen); + char * p = (char *)getFileExtension(filename, 0, 0, NULL, &extlen); if (p) strncat(extension, p, sizeof(extension)-1); while (1) { index++; @@ -163,6 +163,32 @@ int findNextFileIndex(char * filename, uint8_t size, const char * directory) } } +const char * getFileExtension(const char * filename, uint8_t size, uint8_t extMaxLen, uint8_t *fnlen, uint8_t *extlen) +{ + int len = size; + if (!size) { + len = strlen(filename); + } + if (!extMaxLen) { + extMaxLen = LEN_FILE_EXTENSION_MAX; + } + if (fnlen != NULL) { + *fnlen = (uint8_t)len; + } + for (int i=len-1; i >= 0 && len-i <= extMaxLen; --i) { + if (filename[i] == '.') { + if (extlen) { + *extlen = len-i; + } + return &filename[i]; + } + } + if (extlen != NULL) { + *extlen = 0; + } + return NULL; +} + /** Check if given extension exists in a list of extensions. @param extension The extension to search for, including leading period. @@ -198,7 +224,7 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen static uint16_t lastpopupMenuOffset = 0; FILINFO fno; DIR dir; - char *fnExt; + const char * fnExt; uint8_t fnLen, extLen; char tmpExt[LEN_FILE_EXTENSION_MAX+1] = "\0"; diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index 09ebfe853..f30a8ac02 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -111,32 +111,7 @@ inline const pm_char * SDCARD_ERROR(FRESULT result) #endif // NOTE: 'size' must = 0 or be a valid character position within 'filename' array -- it is NOT validated -template -T * getFileExtension(T * filename, uint8_t size=0, uint8_t extMaxLen=0, uint8_t *fnlen=NULL, uint8_t *extlen=NULL) -{ - int len = size; - if (!size) { - len = strlen(filename); - } - if (!extMaxLen) { - extMaxLen = LEN_FILE_EXTENSION_MAX; - } - if (fnlen != NULL) { - *fnlen = (uint8_t)len; - } - for (int i=len-1; i >= 0 && len-i <= extMaxLen; --i) { - if (filename[i] == '.') { - if (extlen) { - *extlen = len-i; - } - return &filename[i]; - } - } - if (extlen != NULL) { - *extlen = 0; - } - return NULL; -} +const char * getFileExtension(const char * filename, uint8_t size=0, uint8_t extMaxLen=0, uint8_t *fnlen=NULL, uint8_t *extlen=NULL); #if defined(PCBTARANIS) #define O9X_FOURCC 0x3378396F // o9x for Taranis diff --git a/radio/src/tests/colorlcd.cpp b/radio/src/tests/colorlcd.cpp new file mode 100644 index 000000000..59d83c9e1 --- /dev/null +++ b/radio/src/tests/colorlcd.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "gtests.h" + +#if defined(COLORLCD) + +#include "colors.h" + +TEST(color, RGB) +{ + // test conversion from RGB to RGB565 (5 bits for R, 6 bits for G, 5 bits for B) + EXPECT_EQ(RGB(0, 0, 0), (uint16_t)0x0000); + EXPECT_EQ(RGB(255, 255, 255), (uint16_t)0xFFFF); + + EXPECT_EQ(RGB(255, 0, 0), (uint16_t)0xF800); + EXPECT_EQ(RGB(0, 255, 0), (uint16_t)0x07E0); + EXPECT_EQ(RGB(0, 0, 255), (uint16_t)0x001F); + + EXPECT_EQ(RGB(30, 40, 150), (uint16_t)0x1952); +} + +TEST(color, ARGB) +{ + // test conversion from RGB to ARGB4444 (4 bits for alpha, 4 bits for R, 4 bits for G, 4 bits for B) + EXPECT_EQ(ARGB(0, 0, 0, 0), (uint16_t)0x0000); + EXPECT_EQ(ARGB(255, 255, 255, 255), (uint16_t)0xFFFF); + + EXPECT_EQ(ARGB(255, 0, 0, 0), (uint16_t)0xF000); + EXPECT_EQ(ARGB(0, 255, 0, 0), (uint16_t)0x0F00); + EXPECT_EQ(ARGB(0, 0, 255, 0), (uint16_t)0x00F0); + EXPECT_EQ(ARGB(0, 0, 0, 255), (uint16_t)0x000F); + + EXPECT_EQ(ARGB(128, 30, 40, 150), (uint16_t)0x8129); +} + +#endif \ No newline at end of file diff --git a/radio/src/thirdparty/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c b/radio/src/thirdparty/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c index fe0ef200e..ac61bf214 100644 --- a/radio/src/thirdparty/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c +++ b/radio/src/thirdparty/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c @@ -138,7 +138,7 @@ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ -static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; +static const __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/