Make TimeKeeper a static member of Display.
This commit is contained in:
parent
9140ba5fb4
commit
74404b1a44
@ -12,12 +12,12 @@
|
|||||||
// We must use a mutex to protect it.
|
// We must use a mutex to protect it.
|
||||||
_lock_t Display::ScopedLock::lv_lock_;
|
_lock_t Display::ScopedLock::lv_lock_;
|
||||||
|
|
||||||
std::unordered_map<const char *, Display::Timer>
|
// Static TimeKeeper for managing ESP timers across all displays.
|
||||||
Display::TimeKeeper::managed_timers_;
|
Display::TimeKeeper Display::timers_;
|
||||||
|
|
||||||
Display::Display(IPanelDevice &device) :
|
Display::Display(IPanelDevice &device) :
|
||||||
panel_(device),
|
panel_(device),
|
||||||
lv_tick_timer_(nullptr)
|
lv_buf_(nullptr)
|
||||||
{
|
{
|
||||||
if (!lv_is_initialized()) {
|
if (!lv_is_initialized()) {
|
||||||
ESP_LOGI(TAG, "Initialize LVGL");
|
ESP_LOGI(TAG, "Initialize LVGL");
|
||||||
@ -29,30 +29,8 @@ Display::Display(IPanelDevice &device) :
|
|||||||
// associate the i2c panel handle to the display
|
// associate the i2c panel handle to the display
|
||||||
lv_display_set_user_data(lv_display_, panel_.esp_panel_);
|
lv_display_set_user_data(lv_display_, panel_.esp_panel_);
|
||||||
|
|
||||||
// Create draw buffer.
|
register_draw_buffer();
|
||||||
ESP_LOGI(TAG, "Allocate separate LVGL draw buffers");
|
|
||||||
lv_buf_ = heap_caps_calloc(1, panel_.device_->lv_buf_size_,
|
|
||||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
|
||||||
assert(lv_buf_);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Set LVGL draw buffers");
|
|
||||||
// Color format must be set first, LVGL9 suooprt new monochromatic format.
|
|
||||||
lv_display_set_color_format(lv_display_, LV_COLOR_FORMAT_I1);
|
|
||||||
lv_display_set_buffers(lv_display_, lv_buf_, nullptr,
|
|
||||||
panel_.device_->lv_buf_size_,
|
|
||||||
LV_DISPLAY_RENDER_MODE_FULL);
|
|
||||||
lv_display_set_rotation(lv_display_, LV_DISPLAY_ROTATION_0);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Set LVGL callback for flushing to the display");
|
|
||||||
lv_display_set_flush_cb(lv_display_, Display::lvgl_flush_cb);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Register io panel callback for LVGL flush ready notification");
|
|
||||||
const esp_lcd_panel_io_callbacks_t cbs = {
|
|
||||||
.on_color_trans_done = Display::lvgl_flush_ready,
|
|
||||||
};
|
|
||||||
ESP_ERROR_CHECK(
|
|
||||||
esp_lcd_panel_io_register_event_callbacks(panel_.esp_io_, &cbs,
|
|
||||||
lv_display_));
|
|
||||||
register_lvgl_tick_timer();
|
register_lvgl_tick_timer();
|
||||||
|
|
||||||
// TODO: What is this
|
// TODO: What is this
|
||||||
@ -155,13 +133,40 @@ void Display::lvgl_increase_tick(void *)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::register_draw_buffer()
|
||||||
|
{
|
||||||
|
// Create draw buffer.
|
||||||
|
ESP_LOGI(TAG, "Allocate separate LVGL draw buffers");
|
||||||
|
lv_buf_ = heap_caps_calloc(1, panel_.device_->lv_buf_size_,
|
||||||
|
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
|
assert(lv_buf_);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Set LVGL draw buffers");
|
||||||
|
// Color format must be set first, LVGL9 suooprt new monochromatic format.
|
||||||
|
lv_display_set_color_format(lv_display_, LV_COLOR_FORMAT_I1);
|
||||||
|
lv_display_set_buffers(lv_display_, lv_buf_, nullptr,
|
||||||
|
panel_.device_->lv_buf_size_,
|
||||||
|
LV_DISPLAY_RENDER_MODE_FULL);
|
||||||
|
lv_display_set_rotation(lv_display_, LV_DISPLAY_ROTATION_0);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Set LVGL callback for flushing to the display");
|
||||||
|
lv_display_set_flush_cb(lv_display_, Display::lvgl_flush_cb);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Register io panel callback for LVGL flush ready notification");
|
||||||
|
const esp_lcd_panel_io_callbacks_t cbs = {
|
||||||
|
.on_color_trans_done = Display::lvgl_flush_ready,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(
|
||||||
|
esp_lcd_panel_io_register_event_callbacks(panel_.esp_io_, &cbs,
|
||||||
|
lv_display_));
|
||||||
|
}
|
||||||
|
|
||||||
void Display::register_lvgl_tick_timer()
|
void Display::register_lvgl_tick_timer()
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Use esp_timer to increase LVGL tick");
|
ESP_LOGI(TAG, "Use esp_timer to increase LVGL tick");
|
||||||
const esp_timer_create_args_t lvgl_tick_timer_args = {
|
const esp_timer_create_args_t esp_timer_args = {
|
||||||
.callback = &Display::lvgl_increase_tick,
|
.callback = &Display::lvgl_increase_tick,
|
||||||
.name = "lvgl_tick"
|
.name = "lvgl_tick"
|
||||||
};
|
};
|
||||||
TimeKeeper::start_new_timer_periodic(lvgl_tick_timer_args,
|
timers_.start_new_timer_periodic(esp_timer_args, LVGL_TICK_PERIOD_MS * 1000);
|
||||||
LVGL_TICK_PERIOD_MS * 1000);
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,73 @@ class Display {
|
|||||||
esp_timer_handle_t esp_timer_ = nullptr;
|
esp_timer_handle_t esp_timer_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TimeKeeper {
|
||||||
|
using TimerHandle = Timer *;
|
||||||
|
|
||||||
|
// Timers should only be accessed using this method.
|
||||||
|
// For this reason managed_timers_ is private.
|
||||||
|
TimerHandle get_handle(const char *name)
|
||||||
|
{
|
||||||
|
return &managed_timers_.at(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimerHandle operator[](const char * name) { return get_handle(name); }
|
||||||
|
|
||||||
|
TimerHandle create_timer(esp_timer_create_args_t args)
|
||||||
|
{
|
||||||
|
auto rt = managed_timers_.emplace(args.name, args);
|
||||||
|
if (!rt.second) {
|
||||||
|
ESP_LOGE(TAG, "Failed to insert timer into Display::managed_timers_");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &rt.first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] void stop_timer(const char *name)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(esp_timer_stop(get_handle(name)->esp_timer_));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] void delete_timer(const char *name)
|
||||||
|
{
|
||||||
|
managed_timers_.erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] void
|
||||||
|
start_new_timer_periodic(esp_timer_create_args_t args,
|
||||||
|
uint64_t period)
|
||||||
|
{
|
||||||
|
start_timer_periodic(create_timer(args)->args_.name, period);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] void start_timer_periodic(const char *name,
|
||||||
|
uint64_t period)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(
|
||||||
|
esp_timer_start_periodic(get_handle(name)->esp_timer_, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] void
|
||||||
|
start_new_timer_once(esp_timer_create_args_t args,
|
||||||
|
uint64_t timeout_us)
|
||||||
|
{
|
||||||
|
start_timer_once(create_timer(args)->args_.name, timeout_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] void start_timer_once(const char *name,
|
||||||
|
uint64_t timeout_us)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(
|
||||||
|
esp_timer_start_once(get_handle(name)->esp_timer_, timeout_us));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Timers should only be accessed using the get_handle method.
|
||||||
|
// ~Timer() will delete the timer if called.
|
||||||
|
std::unordered_map<const char *, Timer> managed_timers_;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Display(IPanelDevice &device);
|
explicit Display(IPanelDevice &device);
|
||||||
|
|
||||||
@ -71,73 +138,12 @@ public:
|
|||||||
|
|
||||||
[[noreturn]] static void lvgl_port_task(void *arg);
|
[[noreturn]] static void lvgl_port_task(void *arg);
|
||||||
|
|
||||||
struct TimeKeeper {
|
// Public static TimeKeeper for managing ESP timers across all displays.
|
||||||
using TimerHandle = Timer *;
|
static TimeKeeper timers_;
|
||||||
|
|
||||||
// Timers should only be accessed using this method.
|
|
||||||
// For this reason managed_timers_ is private.
|
|
||||||
static TimerHandle get_handle(const char *name)
|
|
||||||
{
|
|
||||||
return &managed_timers_.at(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TimerHandle create_timer(esp_timer_create_args_t args)
|
|
||||||
{
|
|
||||||
auto rt = managed_timers_.emplace(args.name, args);
|
|
||||||
if (!rt.second) {
|
|
||||||
ESP_LOGE(TAG, "Failed to insert timer into Display::managed_timers_");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return &rt.first->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] static void stop_timer(const char *name)
|
|
||||||
{
|
|
||||||
ESP_ERROR_CHECK(esp_timer_stop(get_handle(name)->esp_timer_));
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] static void delete_timer(const char *name)
|
|
||||||
{
|
|
||||||
managed_timers_.erase(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] static void
|
|
||||||
start_new_timer_periodic(esp_timer_create_args_t args,
|
|
||||||
uint64_t period)
|
|
||||||
{
|
|
||||||
start_timer_periodic(create_timer(args)->args_.name, period);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] static void start_timer_periodic(const char *name,
|
|
||||||
uint64_t period)
|
|
||||||
{
|
|
||||||
ESP_ERROR_CHECK(
|
|
||||||
esp_timer_start_periodic(get_handle(name)->esp_timer_, period));
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] static void
|
|
||||||
start_new_timer_once(esp_timer_create_args_t args,
|
|
||||||
uint64_t timeout_us)
|
|
||||||
{
|
|
||||||
start_timer_once(create_timer(args)->args_.name, timeout_us);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] static void start_timer_once(const char *name,
|
|
||||||
uint64_t timeout_us)
|
|
||||||
{
|
|
||||||
ESP_ERROR_CHECK(
|
|
||||||
esp_timer_start_once(get_handle(name)->esp_timer_, timeout_us));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO start_timer_once
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Timers should only be accessed using the get_handle method.
|
|
||||||
// ~Timer() will delete the timer if called.
|
|
||||||
static std::unordered_map<const char *, Timer> managed_timers_;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void register_draw_buffer();
|
||||||
|
|
||||||
void register_lvgl_tick_timer();
|
void register_lvgl_tick_timer();
|
||||||
|
|
||||||
Panel panel_;
|
Panel panel_;
|
||||||
@ -151,9 +157,6 @@ private:
|
|||||||
// @sa Display::set_text
|
// @sa Display::set_text
|
||||||
// @sa lv_display_get_screen_active
|
// @sa lv_display_get_screen_active
|
||||||
std::unordered_map<const char *, lv_obj_t *> lv_objects_;
|
std::unordered_map<const char *, lv_obj_t *> lv_objects_;
|
||||||
|
|
||||||
// TODO: This could be a private struct
|
|
||||||
esp_timer_handle_t lv_tick_timer_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DISPLAY_H
|
#endif // DISPLAY_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user