Add Timer and TimeKeeper to Display.
This commit is contained in:
		
							parent
							
								
									c9ec16d70c
								
							
						
					
					
						commit
						9140ba5fb4
					
				@ -12,6 +12,9 @@
 | 
				
			|||||||
// 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>
 | 
				
			||||||
 | 
					    Display::TimeKeeper::managed_timers_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Display::Display(IPanelDevice &device) :
 | 
					Display::Display(IPanelDevice &device) :
 | 
				
			||||||
    panel_(device),
 | 
					    panel_(device),
 | 
				
			||||||
    lv_tick_timer_(nullptr)
 | 
					    lv_tick_timer_(nullptr)
 | 
				
			||||||
@ -152,15 +155,13 @@ void Display::lvgl_increase_tick(void *)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Display::register_lvgl_tick_timer() // NOLINT(*-convert-member-functions-to-static)
 | 
					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 lvgl_tick_timer_args = {
 | 
				
			||||||
      .callback = &Display::lvgl_increase_tick,
 | 
					      .callback = &Display::lvgl_increase_tick,
 | 
				
			||||||
      .name = "lvgl_tick"
 | 
					      .name = "lvgl_tick"
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  esp_timer_handle_t lvgl_tick_timer = nullptr;
 | 
					  TimeKeeper::start_new_timer_periodic(lvgl_tick_timer_args,
 | 
				
			||||||
  ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
 | 
					                                       LVGL_TICK_PERIOD_MS * 1000);
 | 
				
			||||||
  ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer,
 | 
					 | 
				
			||||||
                                           LVGL_TICK_PERIOD_MS * 1000));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <unordered_map>
 | 
					#include <unordered_map>
 | 
				
			||||||
#include <esp_timer.h>
 | 
					#include <esp_timer.h>
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "panel.h"
 | 
					#include "panel.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -13,6 +14,33 @@
 | 
				
			|||||||
#define LVGL_TASK_PRIORITY     2
 | 
					#define LVGL_TASK_PRIORITY     2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Display {
 | 
					class Display {
 | 
				
			||||||
 | 
					  struct ScopedLock {
 | 
				
			||||||
 | 
					    explicit ScopedLock() { _lock_acquire(&lv_lock_); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ~ScopedLock() { _lock_release(&lv_lock_); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // LVGL library is not thread-safe, this example calls LVGL APIs from tasks.
 | 
				
			||||||
 | 
					    // We must use a mutex to protect it.
 | 
				
			||||||
 | 
					    static _lock_t lv_lock_;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct Timer {
 | 
				
			||||||
 | 
					    explicit Timer(esp_timer_create_args_t args) : args_(args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      ESP_LOGI(TAG, "Creating esp_timer with name: %s", args.name);
 | 
				
			||||||
 | 
					      ESP_ERROR_CHECK(esp_timer_create(&args, &esp_timer_));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ~Timer()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      ESP_ERROR_CHECK(esp_timer_delete(esp_timer_));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [[maybe_unused]] esp_timer_create_args_t args_{};
 | 
				
			||||||
 | 
					    esp_timer_handle_t esp_timer_ = nullptr;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  explicit Display(IPanelDevice &device);
 | 
					  explicit Display(IPanelDevice &device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -43,6 +71,72 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  [[noreturn]] static void lvgl_port_task(void *arg);
 | 
					  [[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_;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  void register_lvgl_tick_timer();
 | 
					  void register_lvgl_tick_timer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,16 +154,6 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // TODO: This could be a private struct
 | 
					  // TODO: This could be a private struct
 | 
				
			||||||
  esp_timer_handle_t lv_tick_timer_;
 | 
					  esp_timer_handle_t lv_tick_timer_;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  struct ScopedLock {
 | 
					 | 
				
			||||||
    explicit ScopedLock() { _lock_acquire(&lv_lock_); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ~ScopedLock() { _lock_release(&lv_lock_); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // LVGL library is not thread-safe, this example calls LVGL APIs from tasks.
 | 
					 | 
				
			||||||
    // We must use a mutex to protect it.
 | 
					 | 
				
			||||||
    static _lock_t lv_lock_;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // DISPLAY_H
 | 
					#endif // DISPLAY_H
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user