diff options
| -rw-r--r-- | src/displayapp/screens/WatchFaceDigital.cpp | 121 | ||||
| -rw-r--r-- | src/displayapp/screens/WatchFaceDigital.h | 12 |
2 files changed, 133 insertions, 0 deletions
diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 3b46c3b..25e86fb 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -3,6 +3,7 @@ #include <date/date.h> #include <lvgl/lvgl.h> #include <cstdio> +#include <FreeRTOS.h> #include "displayapp/screens/BatteryIcon.h" #include "displayapp/screens/BleIcon.h" #include "displayapp/screens/NotificationIcon.h" @@ -77,6 +78,12 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, lv_label_set_text_fmt(label_temp, "??°C"); lv_obj_align(label_temp, nullptr, LV_ALIGN_CENTER, 60, -60); + memfragLabel = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(memfragLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &neofont1); + lv_obj_set_style_local_text_color(memfragLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x272727)); + lv_label_set_text_static(memfragLabel, memfrag_label_text); + lv_obj_align(memfragLabel, nullptr, LV_ALIGN_IN_RIGHT_MID, 0, -50); + label_time = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &neofont3); lv_label_set_text_fmt(label_time, hhmm_label_text); @@ -126,6 +133,7 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); Refresh(); + RefreshStats(); } WatchFaceDigital::~WatchFaceDigital() { @@ -133,6 +141,119 @@ WatchFaceDigital::~WatchFaceDigital() { lv_obj_clean(lv_scr_act()); } +bool WatchFaceDigital::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + if (event == Pinetime::Applications::TouchEvents::Tap) { + RefreshStats(); + } + return false; +} + +namespace { + template <typename Malloc, typename Free> struct AllocStats { + inline AllocStats(const Malloc& m, const Free& f) : ourMalloc(m), ourFree(f) { }; + const Malloc& ourMalloc; + const Free& ourFree; + bool tryAlloc(uint16_t s1, uint16_t s2) { + bool good = false; +#ifndef INFINISIM + portENTER_CRITICAL(); +#endif + void*p1 = ourMalloc(s1); + if (p1 != nullptr) { + if (s2 > 0) { + void*p2 = ourMalloc(s2); + if (p2 != nullptr) { + good = true; + ourFree(p2); + } + } else { + good = true; + } + ourFree(p1); + } +#ifndef INFINISIM + portEXIT_CRITICAL(); +#endif + return good; + } + inline auto stats(uint16_t maximumPlusOne = 10000) { + uint16_t min1 = 0; + uint16_t max1 = 0; + while (1) { + max1 = 1 + max1 * 2; + if (max1 > maximumPlusOne) { + max1 = maximumPlusOne; + break; + } + if (!tryAlloc(max1,0)) { + break; + } + min1 = max1; + } + for (decltype(max1) d; (d = ((max1 - min1) >> 4)) > 0;) { + auto mid = min1 + (d << 3); + if (tryAlloc(mid, 0)) { + min1 = mid; + } else { + max1 = mid; + } + } + uint16_t min2 = 0; + uint16_t max2 = 0; + while (1) { + max2 = 1 + max2 * 2; + if (max2 > min1) { + max2 = min1; max2 += (1 << 3); + break; + } + if (!tryAlloc(min1,max2)) { + break; + } + min2 = max2; + } + for (decltype(max2) d; (d = ((max2 - min2) >> 4)) > 0;) { + auto mid = min2 + (d << 3); + if (tryAlloc(min1, mid)) { + min2 = mid; + } else { + max2 = mid; + } + } + return std::array<uint16_t, 2>({ min1, min2 }); + } + }; + inline void*cppMalloc(uint16_t x) { + return operator new(x); + } + inline void cppFree(void*x) { + operator delete(x); + } + inline auto memfragStats() { +#ifdef INFINISIM + auto a = AllocStats{malloc,free}.stats((200+1)*8); +#else + auto a = AllocStats(pvPortMalloc,vPortFree).stats((200+1)*8); +#endif + // auto a = AllocStats{cppMalloc,cppFree}.stats(200); + auto b = AllocStats{lv_mem_alloc,lv_mem_free}.stats(8008); + // return std::array<uint16_t, 4>{ 1, 10, 100, 1000 }; + return std::array<uint16_t, 4>{ a[0], a[1], b[0], b[1] }; + } +} + +void WatchFaceDigital::RefreshStats() { + char *s = memfrag_label_text; + for (uint16_t x : memfragStats()) { + s += 2; + x >>= 3; + (s--)[0] = '0' + x%10; x /= 10; + (s--)[0] = '0' + x%10; x /= 10; + s[0] = '0' + x%10; x /= 10; + s += 4; + } + lv_label_set_text_static(memfragLabel, memfrag_label_text); +} + void WatchFaceDigital::Refresh() { bool batteryRefreshed = false; diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 1ef9244..76b2f34 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -37,6 +37,8 @@ namespace Pinetime { void Refresh() override; + bool OnTouchEvent(TouchEvents event) override; + private: System::SystemTask& systemTask; uint8_t displayedHour = -1; @@ -56,6 +58,13 @@ namespace Pinetime { char battery_percent_label_text[5] = { '?', '?', '?', '%', 0 }; char battery_voltage_label_text[8] = { '0', '0', '0', '0', ' ', 'm', 'V', 0 }; + char memfrag_label_text[16] = { + '0', '0', '0', '\n', + '0', '0', '0', '\n', + '0', '0', '0', '\n', + '0', '0', '0', 0 + }; + DirtyValue<uint8_t> batteryPercentRemaining {}; DirtyValue<bool> powerPresent {}; DirtyValue<bool> bleState {}; @@ -84,6 +93,7 @@ namespace Pinetime { lv_obj_t* notificationIcon; lv_obj_t* batteryPercentLabel; lv_obj_t* batteryVoltageLabel; + lv_obj_t* memfragLabel; Controllers::DateTime& dateTimeController; Controllers::Battery& batteryController; @@ -94,6 +104,8 @@ namespace Pinetime { Controllers::MotionController& motionController; lv_task_t* taskRefresh; + + void RefreshStats(); }; } } |
