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.
|
||||
_lock_t Display::ScopedLock::lv_lock_;
|
||||
|
||||
std::unordered_map<const char *, Display::Timer>
|
||||
Display::TimeKeeper::managed_timers_;
|
||||
// Static TimeKeeper for managing ESP timers across all displays.
|
||||
Display::TimeKeeper Display::timers_;
|
||||
|
||||
Display::Display(IPanelDevice &device) :
|
||||
panel_(device),
|
||||
lv_tick_timer_(nullptr)
|
||||
lv_buf_(nullptr)
|
||||
{
|
||||
if (!lv_is_initialized()) {
|
||||
ESP_LOGI(TAG, "Initialize LVGL");
|
||||
@ -29,30 +29,8 @@ Display::Display(IPanelDevice &device) :
|
||||
// associate the i2c panel handle to the display
|
||||
lv_display_set_user_data(lv_display_, panel_.esp_panel_);
|
||||
|
||||
// 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_);
|
||||
register_draw_buffer();
|
||||
|
||||
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();
|
||||
|
||||
// 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()
|
||||
{
|
||||
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,
|
||||
.name = "lvgl_tick"
|
||||
};
|
||||
TimeKeeper::start_new_timer_periodic(lvgl_tick_timer_args,
|
||||
LVGL_TICK_PERIOD_MS * 1000);
|
||||
timers_.start_new_timer_periodic(esp_timer_args, LVGL_TICK_PERIOD_MS * 1000);
|
||||
}
|
||||
|
@ -41,6 +41,73 @@ class Display {
|
||||
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:
|
||||
explicit Display(IPanelDevice &device);
|
||||
|
||||
@ -71,73 +138,12 @@ public:
|
||||
|
||||
[[noreturn]] static void lvgl_port_task(void *arg);
|
||||
|
||||
struct TimeKeeper {
|
||||
using TimerHandle = Timer *;
|
||||
|
||||
// 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_;
|
||||
};
|
||||
// Public static TimeKeeper for managing ESP timers across all displays.
|
||||
static TimeKeeper timers_;
|
||||
|
||||
private:
|
||||
void register_draw_buffer();
|
||||
|
||||
void register_lvgl_tick_timer();
|
||||
|
||||
Panel panel_;
|
||||
@ -151,9 +157,6 @@ private:
|
||||
// @sa Display::set_text
|
||||
// @sa lv_display_get_screen_active
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user