diff --git a/lib/btclock/data_handler.cpp b/lib/btclock/data_handler.cpp index 0905e8a..7b63db6 100644 --- a/lib/btclock/data_handler.cpp +++ b/lib/btclock/data_handler.cpp @@ -220,7 +220,7 @@ std::array parseMarketCap(std::uint32_t blockHeight, s std::array ret; std::uint32_t firstIndex = 0; double supply = getSupplyAtBlock(blockHeight); - int64_t marketCap = static_cast(supply * double(price)); + uint64_t marketCap = static_cast(supply * double(price)); ret[0] = getCurrencyCode(currencySymbol) + "/MCAP"; @@ -256,7 +256,7 @@ std::array parseMarketCap(std::uint32_t blockHeight, s ret[i] = ""; } - ret[NUM_SCREENS - groups - 1] = " $ "; + ret[NUM_SCREENS - groups - 1] = std::string(" ") + currencySymbol + " "; for (std::uint32_t i = 0; i < groups; i++) { ret[(NUM_SCREENS - groups + i)] = stringValue.substr(i * 3, 3).c_str(); diff --git a/lib/btclock/utils.cpp b/lib/btclock/utils.cpp index c419603..53212e4 100644 --- a/lib/btclock/utils.cpp +++ b/lib/btclock/utils.cpp @@ -68,7 +68,8 @@ std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters) } else { - sprintf(result, "%llu", (unsigned long long)num); + snprintf(result, sizeof(result), "%llu", (unsigned long long)num); +// sprintf(result, "%llu", (unsigned long long)num); return result; } diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 59b2ec3..3294889 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -45,4 +45,4 @@ CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120 CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n CONFIG_SPIRAM_CACHE_WORKAROUND=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_NEWLIB_NANO_FORMAT=y \ No newline at end of file +#CONFIG_NEWLIB_NANO_FORMAT=y \ No newline at end of file diff --git a/src/fonts/antonio-semibold40.h b/src/fonts/antonio-semibold40.h index 0f8ea5f..13725f9 100644 --- a/src/fonts/antonio-semibold40.h +++ b/src/fonts/antonio-semibold40.h @@ -1526,7 +1526,78 @@ const uint8_t Antonio_SemiBold40pt7bBitmaps[] PROGMEM = { 0x3F, 0xE0, 0x3F, 0xE0, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0x80, - 0x00}; + 0x00, + // euro + 0x00, 0x07, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0x00, + 0x07, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFE, 0x07, 0xFE, 0x07, 0xFC, 0x0F, + 0xF8, 0x0F, 0xF8, 0x1F, 0xF0, 0x0F, 0xF8, 0x3F, 0xE0, 0x1F, 0xF0, 0xFF, + 0x80, 0x3F, 0xE1, 0xFF, 0x00, 0x7F, 0xC3, 0xFE, 0x00, 0xFF, 0x87, 0xFC, + 0x00, 0xFF, 0x0F, 0xF8, 0x01, 0xFE, 0x1F, 0xF0, 0x03, 0xFC, 0x3F, 0xE0, + 0x07, 0xF8, 0x7F, 0xC0, 0x0F, 0xF0, 0xFF, 0x80, 0x1F, 0xE1, 0xFF, 0x00, + 0x3F, 0xC3, 0xFE, 0x00, 0x7F, 0x87, 0xFC, 0x00, 0xFF, 0x0F, 0xF8, 0x01, + 0xFE, 0x1F, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xFF, 0x80, + 0x0F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x07, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, + 0x3F, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0x00, 0x1F, + 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x0F, + 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x03, 0xFC, 0x3F, 0xE0, 0x07, 0xF8, 0x7F, + 0xC0, 0x0F, 0xF0, 0xFF, 0x80, 0x1F, 0xE1, 0xFF, 0x00, 0x3F, 0xC3, 0xFE, + 0x00, 0x7F, 0x87, 0xFC, 0x00, 0xFF, 0x0F, 0xF8, 0x01, 0xFE, 0x1F, 0xF0, + 0x03, 0xFC, 0x3F, 0xE0, 0x07, 0xF8, 0x7F, 0xC0, 0x0F, 0xF0, 0xFF, 0x80, + 0x1F, 0xE1, 0xFF, 0x00, 0x7F, 0xC3, 0xFE, 0x00, 0xFF, 0x87, 0xFC, 0x01, + 0xFF, 0x0F, 0xF8, 0x03, 0xFE, 0x0F, 0xF8, 0x07, 0xFC, 0x1F, 0xF0, 0x0F, + 0xF0, 0x3F, 0xE0, 0x3F, 0xE0, 0x3F, 0xE0, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, + 0x80, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0x80, 0x00, + // pound + 0x00, 0x0F, 0xFC, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x7F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xC0, 0x7F, + 0xFF, 0xFF, 0x83, 0xFF, 0x03, 0xFE, 0x0F, 0xF8, 0x07, 0xF8, 0x3F, 0xC0, + 0x1F, 0xE1, 0xFF, 0x00, 0x3F, 0xC7, 0xFC, 0x00, 0xFF, 0x1F, 0xE0, 0x03, + 0xFC, 0x7F, 0x80, 0x0F, 0xF1, 0xFE, 0x00, 0x3F, 0xC7, 0xF8, 0x00, 0xFF, + 0x1F, 0xF0, 0x03, 0xFC, 0x7F, 0xC0, 0x0F, 0xF1, 0xFF, 0x00, 0x3F, 0xC3, + 0xFC, 0x00, 0xFF, 0x0F, 0xF0, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0xFF, + 0x80, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x1F, 0xF0, + 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x03, 0xFC, 0x00, + 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, + 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFE, 0x3F, + 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFE, 0x00, 0x00, 0x0F, + 0xF8, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x01, 0xFE, + 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x7F, 0xC0, + 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xF0, 0x00, + 0x00, 0x7F, 0xC0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, + 0x1F, 0xF0, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x0F, + 0xF8, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x0F, 0xF8, + 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x1F, 0xF0, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xDF, + 0xFF, 0xFF, 0xFF, + // yen + 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x07, 0xFB, 0xFE, 0x00, 0x1F, 0xF3, + 0xFC, 0x00, 0x3F, 0xE7, 0xFC, 0x00, 0x7F, 0xCF, 0xF8, 0x00, 0xFF, 0x0F, + 0xF0, 0x03, 0xFE, 0x1F, 0xE0, 0x07, 0xFC, 0x3F, 0xE0, 0x0F, 0xF0, 0x7F, + 0xC0, 0x1F, 0xE0, 0x7F, 0x80, 0x7F, 0xC0, 0xFF, 0x80, 0xFF, 0x81, 0xFF, + 0x01, 0xFE, 0x01, 0xFE, 0x03, 0xFC, 0x03, 0xFC, 0x07, 0xF8, 0x07, 0xFC, + 0x1F, 0xF0, 0x0F, 0xF8, 0x3F, 0xC0, 0x0F, 0xF0, 0x7F, 0x80, 0x1F, 0xE0, + 0xFF, 0x00, 0x3F, 0xE3, 0xFC, 0x00, 0x3F, 0xC7, 0xF8, 0x00, 0x7F, 0x8F, + 0xF0, 0x00, 0xFF, 0x9F, 0xE0, 0x00, 0xFF, 0x7F, 0x80, 0x01, 0xFE, 0xFF, + 0x00, 0x03, 0xFD, 0xFE, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, + 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0x00, + 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x7F, 0xFC, 0x00, 0x00, 0xFF, 0xF8, 0x00, + 0x00, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0x80, 0x07, + 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xF8, 0x3F, + 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xC0, 0x00, 0x00, + 0xFF, 0x80, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x07, + 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, + 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, + 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x0F, 0xF8, + 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x7F, 0xC0, + 0x00, 0x00, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x03, 0xFE, 0x00, + 0x00, 0x07, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x00, + 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x7F, 0xC0, 0x00 + }; const GFXglyph Antonio_SemiBold40pt7bGlyphs[] PROGMEM = { {0, 1, 1, 17, 0, 0}, // 0x20 ' ' @@ -1588,10 +1659,10 @@ const GFXglyph Antonio_SemiBold40pt7bGlyphs[] PROGMEM = { {10963, 28, 67, 32, 2, -66}, // 0x58 'X' {11198, 31, 67, 32, 1, -66}, // 0x59 'Y' {11458, 23, 67, 27, 3, -66}, // 0x5A 'Z' - {11651, 17, 70, 26, 6, -66}, // 0x5B '[' - {11800, 24, 67, 30, 3, -66}, // 0x5C '\' - {12001, 16, 70, 26, 4, -66}, // 0x5D ']' - {12141, 29, 35, 37, 4, -66}, // 0x5E '^' + {18021, 31, 69, 37, 2, -67}, // 0x5B '[' --> euro { 18290, 31, 69, 37, 2, -67 } was {11651, 17, 70, 26, 6, -66} + {11800, 24, 67, 30, 3, -66}, // 0x5C '\' + {18557, 30, 68, 36, 3, -67 }, // 0x5D ']' --> pound { 0, 30, 68, 36, 3, -67 } was {12001, 16, 70, 26, 4, -66} + {18812, 31, 67, 32, 1, -66 }, // 0x5E '^' --> yen { 0, 31, 67, 32, 1, -66 } was {12141, 29, 35, 37, 4, -66 {12268, 25, 7, 29, 2, 2}, // 0x5F '_' {12290, 12, 15, 16, 2, -77}, // 0x60 '`' {12313, 27, 59, 36, 4, -57}, // 0x61 'a' @@ -1623,10 +1694,13 @@ const GFXglyph Antonio_SemiBold40pt7bGlyphs[] PROGMEM = { {17509, 20, 75, 27, 4, -67}, // 0x7B '{' {17697, 9, 75, 21, 6, -70}, // 0x7C '|' {17782, 19, 75, 27, 4, -67}, // 0x7D '}' - {17961, 34, 14, 43, 4, -44}, {18021, 31, 69, 37, 2, -67}}; // 0x7E '~' + {17961, 34, 14, 43, 4, -44}}; // 0x7E '~' + + +//, {18021, 31, 69, 37, 2, -67} const GFXfont Antonio_SemiBold40pt7b PROGMEM = { (uint8_t *)Antonio_SemiBold40pt7bBitmaps, - (GFXglyph *)Antonio_SemiBold40pt7bGlyphs, 0x20, 0x7E, 101}; + (GFXglyph *)Antonio_SemiBold40pt7bGlyphs, 0x20, 0x7E, 100}; // Approx. 18961 bytes diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index 7688fc8..a301f17 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -132,6 +132,12 @@ std::mutex epdMutex[NUM_SCREENS]; uint8_t qrcode[800]; +#ifdef IS_BTCLOCK_V8 +#define EPD_TASK_STACK_SIZE 4096 +#else +#define EPD_TASK_STACK_SIZE 2048 +#endif + void forceFullRefresh() { for (uint i = 0; i < NUM_SCREENS; i++) @@ -170,7 +176,7 @@ void setupDisplays() updateQueue = xQueueCreate(UPDATE_QUEUE_SIZE, sizeof(UpdateDisplayTaskItem)); - xTaskCreate(prepareDisplayUpdateTask, "PrepareUpd", 4096, NULL, 11, NULL); + xTaskCreate(prepareDisplayUpdateTask, "PrepareUpd", EPD_TASK_STACK_SIZE, NULL, 11, NULL); for (uint i = 0; i < NUM_SCREENS; i++) { @@ -180,7 +186,7 @@ void setupDisplays() int *taskParam = new int; *taskParam = i; - xTaskCreate(updateDisplay, ("EpdUpd" + String(i)).c_str(), 4096, taskParam, + xTaskCreate(updateDisplay, ("EpdUpd" + String(i)).c_str(), EPD_TASK_STACK_SIZE, taskParam, 11, &tasks[i]); // create task } @@ -190,7 +196,7 @@ void setupDisplays() setFgColor(GxEPD_BLACK); setBgColor(GxEPD_WHITE); - epdContent = {" ", " ", " ", " ", " ", " ", " "}; + epdContent.fill(""); } else { diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index 738f4f5..d5dba86 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -300,7 +300,8 @@ JsonDocument getLedStatusObject() uint green = (pixColor >> 8) & 0xFF; uint blue = pixColor & 0xFF; char hexColor[8]; - sprintf(hexColor, "#%02X%02X%02X", red, green, blue); + snprintf(hexColor, sizeof(hexColor), "#%02X%02X%02X", red, green, blue); + JsonObject object = colors.add(); object["red"] = red; diff --git a/test/test_datahandler/test_main.cpp b/test/test_datahandler/test_main.cpp index 14f3a93..29d337f 100644 --- a/test/test_datahandler/test_main.cpp +++ b/test/test_datahandler/test_main.cpp @@ -1,6 +1,18 @@ #include #include +template +std::string joinArrayWithBrackets(const std::array& arr, const std::string& separator = " ") { + std::ostringstream result; + for (size_t i = 0; i < N; ++i) { + if (i > 0) { + result << separator; + } + result << '[' << arr[i] << ']'; + } + return result.str(); +} + void setUp(void) { // set stuff up here @@ -100,6 +112,24 @@ void test_Mcap1TrillionUsd(void) TEST_ASSERT_EQUAL_STRING("T", output[NUM_SCREENS - 1].c_str()); } +void test_Mcap1TrillionUsdSmallChars(void) +{ + std::array output = parseMarketCap(831000, 52000, '$', false); + TEST_ASSERT_EQUAL_STRING("USD/MCAP", output[0].c_str()); + + std::string joined = joinArrayWithBrackets(output); + + + + TEST_ASSERT_EQUAL_STRING_MESSAGE(" $ ", output[NUM_SCREENS - 6].c_str(), joined.c_str()); + + TEST_ASSERT_EQUAL_STRING_MESSAGE(" 1", output[NUM_SCREENS - 5].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("020", output[NUM_SCREENS - 4].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("825", output[NUM_SCREENS - 3].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("000", output[NUM_SCREENS - 2].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("000", output[NUM_SCREENS - 1].c_str(), joined.c_str()); +} + void test_Mcap1TrillionEur(void) { std::array output = parseMarketCap(831000, 52000, CURRENCY_EUR, true); @@ -112,6 +142,23 @@ void test_Mcap1TrillionEur(void) TEST_ASSERT_EQUAL_STRING("T", output[NUM_SCREENS - 1].c_str()); } +void test_Mcap1TrillionEurSmallChars(void) +{ + std::array output = parseMarketCap(831000, 52000, CURRENCY_EUR, false); + TEST_ASSERT_EQUAL_STRING("EUR/MCAP", output[0].c_str()); + + std::string joined = joinArrayWithBrackets(output); + + char result[4]; + snprintf(result, sizeof(result), " %c ", CURRENCY_EUR); + TEST_ASSERT_EQUAL_STRING(result, output[NUM_SCREENS - 6].c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE(" 1", output[NUM_SCREENS - 5].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("020", output[NUM_SCREENS - 4].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("825", output[NUM_SCREENS - 3].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("000", output[NUM_SCREENS - 2].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("000", output[NUM_SCREENS - 1].c_str(), joined.c_str()); +} + void test_Mcap1TrillionJpy(void) { std::array output = parseMarketCap(831000, 52000, CURRENCY_JPY, true); @@ -124,6 +171,21 @@ void test_Mcap1TrillionJpy(void) TEST_ASSERT_EQUAL_STRING("T", output[NUM_SCREENS - 1].c_str()); } +void test_Mcap1TrillionJpySmallChars(void) +{ + std::array output = parseMarketCap(831000, 52000, CURRENCY_JPY, false); + TEST_ASSERT_EQUAL_STRING("JPY/MCAP", output[0].c_str()); + + char result[4]; + snprintf(result, sizeof(result), " %c ", CURRENCY_JPY); + TEST_ASSERT_EQUAL_STRING(result, output[NUM_SCREENS - 6].c_str()); + TEST_ASSERT_EQUAL_STRING(" 1", output[NUM_SCREENS - 5].c_str()); + TEST_ASSERT_EQUAL_STRING("020", output[NUM_SCREENS - 4].c_str()); + TEST_ASSERT_EQUAL_STRING("825", output[NUM_SCREENS - 3].c_str()); + TEST_ASSERT_EQUAL_STRING("000", output[NUM_SCREENS - 2].c_str()); + TEST_ASSERT_EQUAL_STRING("000", output[NUM_SCREENS - 1].c_str()); +} + // not needed when using generate_test_runner.rb int runUnityTests(void) { @@ -136,8 +198,11 @@ int runUnityTests(void) RUN_TEST(test_PriceOf100kusd); RUN_TEST(test_McapLowerUsd); RUN_TEST(test_Mcap1TrillionUsd); + RUN_TEST(test_Mcap1TrillionUsdSmallChars); RUN_TEST(test_Mcap1TrillionEur); + RUN_TEST(test_Mcap1TrillionEurSmallChars); RUN_TEST(test_Mcap1TrillionJpy); + RUN_TEST(test_Mcap1TrillionJpySmallChars); return UNITY_END(); }