1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

refactor(tmr): rename lv_tmr to lv_timer

This commit is contained in:
Gabor Kiss-Vamosi 2020-11-27 10:05:02 +01:00
parent be72cad1c8
commit 57734ff3c5
23 changed files with 547 additions and 548 deletions

View File

@ -257,7 +257,7 @@ typedef void * lv_img_decoder_user_data_t;
#define LV_ATTRIBUTE_TICK_INC #define LV_ATTRIBUTE_TICK_INC
/* Define a custom attribute to `lv_task_handler` function */ /* Define a custom attribute to `lv_task_handler` function */
#define LV_ATTRIBUTE_TMR_HANDLER #define LV_ATTRIBUTE_TIMER_HANDLER
/* Define a custom attribute to `lv_disp_flush_ready` function */ /* Define a custom attribute to `lv_disp_flush_ready` function */
#define LV_ATTRIBUTE_FLUSH_READY #define LV_ATTRIBUTE_FLUSH_READY

2
lvgl.h
View File

@ -24,7 +24,7 @@ extern "C" {
*********************/ *********************/
#include "src/lv_misc/lv_log.h" #include "src/lv_misc/lv_log.h"
#include "src/lv_misc/lv_tmr.h" #include <lvgl/src/lv_misc/lv_timer.h>
#include "src/lv_misc/lv_math.h" #include "src/lv_misc/lv_math.h"
#include "src/lv_misc/lv_async.h" #include "src/lv_misc/lv_async.h"

View File

@ -27,9 +27,9 @@ extern "C" {
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
static inline LV_ATTRIBUTE_TMR_HANDLER uint32_t lv_task_handler(void) static inline LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_task_handler(void)
{ {
return lv_tmr_handler(); return lv_timer_handler();
} }
/********************** /**********************

View File

@ -632,11 +632,11 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#endif #endif
/* Define a custom attribute to `lv_task_handler` function */ /* Define a custom attribute to `lv_task_handler` function */
#ifndef LV_ATTRIBUTE_TMR_HANDLER #ifndef LV_ATTRIBUTE_TIMER_HANDLER
# ifdef CONFIG_LV_ATTRIBUTE_TMR_HANDLER # ifdef CONFIG_LV_ATTRIBUTE_TIMER_HANDLER
# define LV_ATTRIBUTE_TMR_HANDLER CONFIG_LV_ATTRIBUTE_TMR_HANDLER # define LV_ATTRIBUTE_TIMER_HANDLER CONFIG_LV_ATTRIBUTE_TIMER_HANDLER
# else # else
# define LV_ATTRIBUTE_TMR_HANDLER # define LV_ATTRIBUTE_TIMER_HANDLER
# endif # endif
#endif #endif

View File

@ -367,7 +367,7 @@ void lv_disp_clean_dcache(lv_disp_t * disp)
* @param disp pointer to a display * @param disp pointer to a display
* @return pointer to the display refresher task. (NULL on error) * @return pointer to the display refresher task. (NULL on error)
*/ */
lv_tmr_t * _lv_disp_get_refr_task(lv_disp_t * disp) lv_timer_t * _lv_disp_get_refr_task(lv_disp_t * disp)
{ {
if(!disp) disp = lv_disp_get_default(); if(!disp) disp = lv_disp_get_default();
if(!disp) { if(!disp) {

View File

@ -145,7 +145,7 @@ void lv_disp_clean_dcache(lv_disp_t * disp);
* @param disp pointer to a display * @param disp pointer to a display
* @return pointer to the display refresher task. (NULL on error) * @return pointer to the display refresher task. (NULL on error)
*/ */
lv_tmr_t * _lv_disp_get_refr_task(lv_disp_t * disp); lv_timer_t * _lv_disp_get_refr_task(lv_disp_t * disp);
/*------------------------------------------------ /*------------------------------------------------
* To improve backward compatibility * To improve backward compatibility

View File

@ -14,7 +14,7 @@
#include "lv_refr.h" #include "lv_refr.h"
#include "../lv_hal/lv_hal_tick.h" #include "../lv_hal/lv_hal_tick.h"
#include "../lv_misc/lv_tmr.h" #include "../lv_misc/lv_timer.h"
#include "../lv_misc/lv_math.h" #include "../lv_misc/lv_math.h"
/********************* /*********************
@ -70,7 +70,7 @@ void _lv_indev_init(void)
* Called periodically to read the input devices * Called periodically to read the input devices
* @param param pointer to and input device to read * @param param pointer to and input device to read
*/ */
void _lv_indev_read_task(lv_tmr_t * task) void _lv_indev_read_task(lv_timer_t * task)
{ {
LV_LOG_TRACE("indev read task started"); LV_LOG_TRACE("indev read task started");
@ -361,7 +361,7 @@ lv_obj_t * lv_indev_get_obj_act(void)
* @param indev pointer to an input device * @param indev pointer to an input device
* @return pointer to the indev read refresher task. (NULL on error) * @return pointer to the indev read refresher task. (NULL on error)
*/ */
lv_tmr_t * lv_indev_get_read_task(lv_disp_t * indev) lv_timer_t * lv_indev_get_read_task(lv_disp_t * indev)
{ {
if(!indev) { if(!indev) {
LV_LOG_WARN("lv_indev_get_read_task: indev was NULL"); LV_LOG_WARN("lv_indev_get_read_task: indev was NULL");

View File

@ -38,7 +38,7 @@ void _lv_indev_init(void);
* Called periodically to read the input devices * Called periodically to read the input devices
* @param task pointer to the task itself * @param task pointer to the task itself
*/ */
void _lv_indev_read_task(lv_tmr_t * task); void _lv_indev_read_task(lv_timer_t * task);
/** /**
* Get the currently processed input device. Can be used in action functions too. * Get the currently processed input device. Can be used in action functions too.
@ -171,7 +171,7 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point);
* @param indev pointer to an inout device * @param indev pointer to an inout device
* @return pointer to the indev read refresher task. (NULL on error) * @return pointer to the indev read refresher task. (NULL on error)
*/ */
lv_tmr_t * lv_indev_get_read_task(lv_disp_t * indev); lv_timer_t * lv_indev_get_read_task(lv_disp_t * indev);
/********************** /**********************
* MACROS * MACROS

View File

@ -15,7 +15,7 @@
#include "../lv_themes/lv_theme.h" #include "../lv_themes/lv_theme.h"
#include "../lv_draw/lv_draw.h" #include "../lv_draw/lv_draw.h"
#include "../lv_misc/lv_anim.h" #include "../lv_misc/lv_anim.h"
#include "../lv_misc/lv_tmr.h" #include "../lv_misc/lv_timer.h"
#include "../lv_misc/lv_async.h" #include "../lv_misc/lv_async.h"
#include "../lv_misc/lv_fs.h" #include "../lv_misc/lv_fs.h"
#include "../lv_misc/lv_gc.h" #include "../lv_misc/lv_gc.h"
@ -98,7 +98,7 @@ void lv_init(void)
/*Initialize the lv_misc modules*/ /*Initialize the lv_misc modules*/
_lv_mem_init(); _lv_mem_init();
_lv_tmr_core_init(); _lv_timer_core_init();
#if LV_USE_FILESYSTEM #if LV_USE_FILESYSTEM
_lv_fs_init(); _lv_fs_init();

View File

@ -11,7 +11,7 @@
#include "lv_disp.h" #include "lv_disp.h"
#include "../lv_hal/lv_hal_tick.h" #include "../lv_hal/lv_hal_tick.h"
#include "../lv_hal/lv_hal_disp.h" #include "../lv_hal/lv_hal_disp.h"
#include "../lv_misc/lv_tmr.h" #include "../lv_misc/lv_timer.h"
#include "../lv_misc/lv_mem.h" #include "../lv_misc/lv_mem.h"
#include "../lv_misc/lv_math.h" #include "../lv_misc/lv_math.h"
#include "../lv_misc/lv_gc.h" #include "../lv_misc/lv_gc.h"
@ -144,7 +144,7 @@ void _lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
lv_area_copy(&disp->inv_areas[disp->inv_p], &scr_area); lv_area_copy(&disp->inv_areas[disp->inv_p], &scr_area);
} }
disp->inv_p++; disp->inv_p++;
lv_tmr_pause(disp->refr_task, false); lv_timer_pause(disp->refr_task, false);
} }
} }
@ -172,7 +172,7 @@ void _lv_refr_set_disp_refreshing(lv_disp_t * disp)
* Called periodically to handle the refreshing * Called periodically to handle the refreshing
* @param task pointer to the task itself * @param task pointer to the task itself
*/ */
void _lv_disp_refr_task(lv_tmr_t * tmr) void _lv_disp_refr_task(lv_timer_t * tmr)
{ {
LV_LOG_TRACE("lv_refr_task: started"); LV_LOG_TRACE("lv_refr_task: started");
@ -185,7 +185,7 @@ void _lv_disp_refr_task(lv_tmr_t * tmr)
/* Ensure the task does not run again automatically. /* Ensure the task does not run again automatically.
* This is done before refreshing in case refreshing invalidates something else. * This is done before refreshing in case refreshing invalidates something else.
*/ */
lv_tmr_pause(tmr, true); lv_timer_pause(tmr, true);
#endif #endif
/*Do nothing if there is no active screen*/ /*Do nothing if there is no active screen*/

View File

@ -82,7 +82,7 @@ void _lv_refr_set_disp_refreshing(lv_disp_t * disp);
* Called periodically to handle the refreshing * Called periodically to handle the refreshing
* @param task pointer to the task itself * @param task pointer to the task itself
*/ */
void _lv_disp_refr_task(lv_tmr_t * task); void _lv_disp_refr_task(lv_timer_t * task);
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS

View File

@ -137,7 +137,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
disp_def = disp; /*Temporarily change the default screen to create the default screens on the disp_def = disp; /*Temporarily change the default screen to create the default screens on the
new display*/ new display*/
/*Create a refresh task*/ /*Create a refresh task*/
disp->refr_task = lv_tmr_create(_lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, disp); disp->refr_task = lv_timer_create(_lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, disp);
LV_ASSERT_MEM(disp->refr_task); LV_ASSERT_MEM(disp->refr_task);
if(disp->refr_task == NULL) return NULL; if(disp->refr_task == NULL) return NULL;
@ -168,7 +168,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
disp_def = disp_def_tmp; /*Revert the default display*/ disp_def = disp_def_tmp; /*Revert the default display*/
lv_tmr_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/ lv_timer_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
/*Can't handle this case later so add an error*/ /*Can't handle this case later so add an error*/
if(lv_disp_is_true_double_buf(disp) && disp->driver.set_px_cb) { if(lv_disp_is_true_double_buf(disp) && disp->driver.set_px_cb) {

View File

@ -21,7 +21,7 @@ extern "C" {
#include "../lv_misc/lv_color.h" #include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_area.h" #include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_ll.h" #include "../lv_misc/lv_ll.h"
#include "../lv_misc/lv_tmr.h" #include "../lv_misc/lv_timer.h"
/********************* /*********************
* DEFINES * DEFINES
@ -149,7 +149,7 @@ typedef struct _disp_t {
lv_disp_drv_t driver; lv_disp_drv_t driver;
/**< A task which periodically checks the dirty areas and refreshes them*/ /**< A task which periodically checks the dirty areas and refreshes them*/
lv_tmr_t * refr_task; lv_timer_t * refr_task;
/** Screens of the display*/ /** Screens of the display*/
lv_ll_t scr_ll; lv_ll_t scr_ll;

View File

@ -92,7 +92,7 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
indev->group = NULL; indev->group = NULL;
indev->btn_points = NULL; indev->btn_points = NULL;
indev->driver.read_task = lv_tmr_create(_lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, indev); indev->driver.read_task = lv_timer_create(_lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, indev);
return indev; return indev;
} }

View File

@ -20,7 +20,7 @@ extern "C" {
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "../lv_misc/lv_area.h" #include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_tmr.h" #include "../lv_misc/lv_timer.h"
/********************* /*********************
* DEFINES * DEFINES
@ -100,7 +100,7 @@ typedef struct _lv_indev_drv_t {
struct _disp_t * disp; struct _disp_t * disp;
/**< Task to read the periodically read the input device*/ /**< Task to read the periodically read the input device*/
lv_tmr_t * read_task; lv_timer_t * read_task;
/**< Number of pixels to slide before actually drag the object*/ /**< Number of pixels to slide before actually drag the object*/
uint8_t scroll_limit; uint8_t scroll_limit;

View File

@ -13,7 +13,7 @@
#include <string.h> #include <string.h>
#include "../lv_misc/lv_debug.h" #include "../lv_misc/lv_debug.h"
#include "../lv_hal/lv_hal_tick.h" #include "../lv_hal/lv_hal_tick.h"
#include "lv_tmr.h" #include <lvgl/src/lv_misc/lv_timer.h>
#include "lv_math.h" #include "lv_math.h"
#include "lv_gc.h" #include "lv_gc.h"
@ -34,7 +34,7 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void anim_task(lv_tmr_t * param); static void anim_task(lv_timer_t * param);
static void anim_mark_list_change(void); static void anim_mark_list_change(void);
static bool anim_ready_handler(lv_anim_t * a); static bool anim_ready_handler(lv_anim_t * a);
@ -43,7 +43,7 @@ static bool anim_ready_handler(lv_anim_t * a);
**********************/ **********************/
static uint32_t last_task_run; static uint32_t last_task_run;
static bool anim_list_changed; static bool anim_list_changed;
static lv_tmr_t * _lv_anim_tmr; static lv_timer_t * _lv_anim_tmr;
const lv_anim_path_t lv_anim_path_def = {.cb = lv_anim_path_linear}; const lv_anim_path_t lv_anim_path_def = {.cb = lv_anim_path_linear};
/********************** /**********************
@ -61,7 +61,7 @@ void _lv_anim_core_init(void)
{ {
_lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t)); _lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t));
last_task_run = lv_tick_get(); last_task_run = lv_tick_get();
_lv_anim_tmr = lv_tmr_create(anim_task, LV_DISP_DEF_REFR_PERIOD, NULL); _lv_anim_tmr = lv_timer_create(anim_task, LV_DISP_DEF_REFR_PERIOD, NULL);
anim_mark_list_change(); /*Turn off the animation task*/ anim_mark_list_change(); /*Turn off the animation task*/
anim_list_changed = false; /*The list has not actually changed*/ anim_list_changed = false; /*The list has not actually changed*/
} }
@ -438,7 +438,7 @@ lv_anim_value_t lv_anim_path_step(const lv_anim_path_t * path, const lv_anim_t *
* Periodically handle the animations. * Periodically handle the animations.
* @param param unused * @param param unused
*/ */
static void anim_task(lv_tmr_t * param) static void anim_task(lv_timer_t * param)
{ {
(void)param; (void)param;
@ -554,8 +554,8 @@ static void anim_mark_list_change(void)
{ {
anim_list_changed = true; anim_list_changed = true;
if(_lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll)) == NULL) if(_lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll)) == NULL)
lv_tmr_pause(_lv_anim_tmr, true); lv_timer_pause(_lv_anim_tmr, true);
else else
lv_tmr_pause(_lv_anim_tmr, false); lv_timer_pause(_lv_anim_tmr, false);
} }
#endif #endif

View File

@ -21,7 +21,7 @@
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void lv_async_task_cb(lv_tmr_t * task); static void lv_async_task_cb(lv_timer_t * task);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@ -45,7 +45,7 @@ lv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data)
/* Create a new task */ /* Create a new task */
/* Use highest priority so that it will run before a refresh */ /* Use highest priority so that it will run before a refresh */
lv_tmr_t * task = lv_tmr_create(lv_async_task_cb, 0, info); lv_timer_t * task = lv_timer_create(lv_async_task_cb, 0, info);
if(task == NULL) { if(task == NULL) {
lv_mem_free(info); lv_mem_free(info);
@ -57,7 +57,7 @@ lv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data)
/* Set the task's user data */ /* Set the task's user data */
task->user_data = info; task->user_data = info;
lv_tmr_set_repeat_count(task, 1); lv_timer_set_repeat_count(task, 1);
return LV_RES_OK; return LV_RES_OK;
} }
@ -65,7 +65,7 @@ lv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static void lv_async_task_cb(lv_tmr_t * task) static void lv_async_task_cb(lv_timer_t * task)
{ {
lv_async_info_t * info = (lv_async_info_t *)task->user_data; lv_async_info_t * info = (lv_async_info_t *)task->user_data;

View File

@ -14,7 +14,7 @@ extern "C" {
* INCLUDES * INCLUDES
*********************/ *********************/
#include "lv_tmr.h" #include <lvgl/src/lv_misc/lv_timer.h>
#include "lv_types.h" #include "lv_types.h"
/********************* /*********************

View File

@ -17,7 +17,7 @@ extern "C" {
#include <stdbool.h> #include <stdbool.h>
#include "lv_mem.h" #include "lv_mem.h"
#include "lv_ll.h" #include "lv_ll.h"
#include "lv_tmr.h" #include <lvgl/src/lv_misc/lv_timer.h>
#include "../lv_draw/lv_img_cache.h" #include "../lv_draw/lv_img_cache.h"
#include "../lv_draw/lv_draw_mask.h" #include "../lv_draw/lv_draw_mask.h"
@ -26,7 +26,7 @@ extern "C" {
*********************/ *********************/
#define LV_ITERATE_ROOTS(f) \ #define LV_ITERATE_ROOTS(f) \
f(lv_ll_t, _lv_tmr_ll) /*Linked list to store the lv_tmr-s*/ \ f(lv_ll_t, _lv_timer_ll) /*Linked list to store the lv_tmr-s*/ \
f(lv_ll_t, _lv_disp_ll) /*Linked list of screens*/ \ f(lv_ll_t, _lv_disp_ll) /*Linked list of screens*/ \
f(lv_ll_t, _lv_indev_ll) /*Linked list of screens*/ \ f(lv_ll_t, _lv_indev_ll) /*Linked list of screens*/ \
f(lv_ll_t, _lv_drv_ll) \ f(lv_ll_t, _lv_drv_ll) \
@ -36,7 +36,7 @@ extern "C" {
f(lv_ll_t, _lv_img_defoder_ll) \ f(lv_ll_t, _lv_img_defoder_ll) \
f(lv_ll_t, _lv_obj_style_trans_ll) \ f(lv_ll_t, _lv_obj_style_trans_ll) \
f(lv_img_cache_entry_t*, _lv_img_cache_array) \ f(lv_img_cache_entry_t*, _lv_img_cache_array) \
f(lv_tmr_t*, _lv_tmr_act) \ f(lv_timer_t*, _lv_timer_act) \
f(lv_mem_buf_arr_t , _lv_mem_buf) \ f(lv_mem_buf_arr_t , _lv_mem_buf) \
f(_lv_draw_mask_saved_arr_t , _lv_draw_mask_list) \ f(_lv_draw_mask_saved_arr_t , _lv_draw_mask_list) \
f(void * , _lv_theme_material_styles) \ f(void * , _lv_theme_material_styles) \
@ -44,7 +44,6 @@ extern "C" {
f(void * , _lv_theme_empty_styles) \ f(void * , _lv_theme_empty_styles) \
f(uint8_t *, _lv_font_decompr_buf) \ f(uint8_t *, _lv_font_decompr_buf) \
#define LV_DEFINE_ROOT(root_type, root_name) root_type root_name; #define LV_DEFINE_ROOT(root_type, root_name) root_type root_name;
#define LV_ROOTS LV_ITERATE_ROOTS(LV_DEFINE_ROOT) #define LV_ROOTS LV_ITERATE_ROOTS(LV_DEFINE_ROOT)

339
src/lv_misc/lv_timer.c Normal file
View File

@ -0,0 +1,339 @@
/**
* @file lv_timer.c
*/
/*********************
* INCLUDES
*********************/
#include <lvgl/src/lv_misc/lv_timer.h>
#include <stddef.h>
#include "../lv_misc/lv_debug.h"
#include "../lv_hal/lv_hal_tick.h"
#include "lv_gc.h"
#if defined(LV_GC_INCLUDE)
#include LV_GC_INCLUDE
#endif /* LV_ENABLE_GC */
/*********************
* DEFINES
*********************/
#define IDLE_MEAS_PERIOD 500 /*[ms]*/
#define DEF_PERIOD 500
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static bool lv_timer_exec(lv_timer_t * timer);
static uint32_t lv_timer_time_remaining(lv_timer_t * timer);
/**********************
* STATIC VARIABLES
**********************/
static bool lv_timer_run = false;
static uint8_t idle_last = 0;
static bool timer_deleted;
static bool timer_created;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Init the lv_timer module
*/
void _lv_timer_core_init(void)
{
_lv_ll_init(&LV_GC_ROOT(_lv_timer_ll), sizeof(lv_timer_t));
/*Initially enable the lv_timer handling*/
lv_timer_enable(true);
}
/**
* Call it periodically to handle lv_timers.
* @return the time after which it must be called again
*/
LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void)
{
LV_LOG_TRACE("lv_timer_handler started");
/*Avoid concurrent running of the timer handler*/
static bool already_running = false;
if(already_running) return 1;
already_running = true;
static uint32_t idle_period_start = 0;
static uint32_t handler_start = 0;
static uint32_t busy_time = 0;
static uint32_t time_till_next;
if(lv_timer_run == false) {
already_running = false; /*Release mutex*/
return 1;
}
handler_start = lv_tick_get();
/* Run all timer from the highest to the lowest priority
* If a lower priority timer is executed check timer again from the highest priority
* but on the priority of executed timers don't run timers before the executed*/
lv_timer_t * next;
bool end_flag;
do {
end_flag = true;
timer_deleted = false;
timer_created = false;
LV_GC_ROOT(_lv_timer_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll));
while(LV_GC_ROOT(_lv_timer_act)) {
/* The timer might be deleted if it runs only once ('repeat_count = 1')
* So get next element until the current is surely valid*/
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_timer_ll), LV_GC_ROOT(_lv_timer_act));
if(lv_timer_exec(LV_GC_ROOT(_lv_timer_act))) {
if(!timer_created && !timer_deleted) {
end_flag = false;
break;
}
}
/*If a timer was created or deleted then this or the next item might be corrupted*/
if(timer_created || timer_deleted) {
break;
}
LV_GC_ROOT(_lv_timer_act) = next; /*Load the next timer*/
}
} while(!end_flag);
busy_time += lv_tick_elaps(handler_start);
uint32_t idle_period_time = lv_tick_elaps(idle_period_start);
if(idle_period_time >= IDLE_MEAS_PERIOD) {
idle_last = (uint32_t)((uint32_t)busy_time * 100) / IDLE_MEAS_PERIOD; /*Calculate the busy percentage*/
idle_last = idle_last > 100 ? 0 : 100 - idle_last; /*But we need idle time*/
busy_time = 0;
idle_period_start = lv_tick_get();
}
time_till_next = LV_NO_TIMER_READY;
next = _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll));
while(next) {
if(next->repeat_count) {
uint32_t delay = lv_timer_time_remaining(next);
if(delay < time_till_next)
time_till_next = delay;
}
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_timer_ll), next); /*Find the next timer*/
}
already_running = false; /*Release the mutex*/
LV_LOG_TRACE("lv_timer_handler ready");
return time_till_next;
}
/**
* Create an "empty" timer. It needs to initialized with at least
* `lv_timer_set_cb` and `lv_timer_set_period`
* @return pointer to the created timer
*/
lv_timer_t * lv_timer_create_basic(void)
{
lv_timer_t * new_timer = NULL;
new_timer = _lv_ll_ins_head(&LV_GC_ROOT(_lv_timer_ll));
LV_ASSERT_MEM(new_timer);
if(new_timer == NULL) return NULL;
new_timer->period = DEF_PERIOD;
new_timer->timer_cb = NULL;
new_timer->repeat_count = -1;
new_timer->paused = 0;
new_timer->last_run = lv_tick_get();
new_timer->user_data = NULL;
timer_created = true;
return new_timer;
}
/**
* Create a new lv_timer
* @param timer_xcb a callback which is the timer itself. It will be called periodically.
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
* the `func_name(object, callback, ...)` convention)
* @param period call period in ms unit
* @param user_data custom parameter
* @return pointer to the new timer
*/
lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * user_data)
{
lv_timer_t * new_timer = lv_timer_create_basic();
LV_ASSERT_MEM(new_timer);
if(new_timer == NULL) return NULL;
lv_timer_set_cb(new_timer, timer_xcb);
lv_timer_set_period(new_timer, period);
new_timer->user_data = user_data;
return new_timer;
}
/**
* Set the callback the timer (the function to call periodically)
* @param timer pointer to a timer
* @param timer_cb the function to call periodically
*/
void lv_timer_set_cb(lv_timer_t * timer, lv_timer_cb_t timer_cb)
{
timer->timer_cb = timer_cb;
}
/**
* Delete a lv_timer
* @param timer pointer to timer created by timer
*/
void lv_timer_del(lv_timer_t * timer)
{
_lv_ll_remove(&LV_GC_ROOT(_lv_timer_ll), timer);
timer_deleted = true;
lv_mem_free(timer);
}
/**
* Pause/resume a timer.
* @param timer pointer to an lv_timer
* @param pause true: pause the timer; false: resume
*/
void lv_timer_pause(lv_timer_t * timer, bool pause)
{
timer->paused = pause;
}
/**
* Set new period for a lv_timer
* @param timer pointer to a lv_timer
* @param period the new period
*/
void lv_timer_set_period(lv_timer_t * timer, uint32_t period)
{
timer->period = period;
}
/**
* Make a lv_timer ready. It will not wait its period.
* @param timer pointer to a lv_timer.
*/
void lv_timer_ready(lv_timer_t * timer)
{
timer->last_run = lv_tick_get() - timer->period - 1;
}
/**
* Set the number of times a timer will repeat.
* @param timer pointer to a lv_timer.
* @param repeat_count -1 : infinity; 0 : stop ; n >0: residual times
*/
void lv_timer_set_repeat_count(lv_timer_t * timer, int32_t repeat_count)
{
timer->repeat_count = repeat_count;
}
/**
* Reset a lv_timer.
* It will be called the previously set period milliseconds later.
* @param timer pointer to a lv_timer.
*/
void lv_timer_reset(lv_timer_t * timer)
{
timer->last_run = lv_tick_get();
}
/**
* Enable or disable the whole lv_timer handling
* @param en: true: lv_timer handling is running, false: lv_timer handling is suspended
*/
void lv_timer_enable(bool en)
{
lv_timer_run = en;
}
/**
* Get idle percentage
* @return the lv_timer idle in percentage
*/
uint8_t lv_timer_get_idle(void)
{
return idle_last;
}
/**
* Iterate through the timers
* @param timer NULL to start iteration or the previous return value to get the next timer
* @return the next timer or NULL if there is no more timer
*/
lv_timer_t * lv_timer_get_next(lv_timer_t * timer)
{
if(timer == NULL) return _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll));
else return _lv_ll_get_next(&LV_GC_ROOT(_lv_timer_ll), timer);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Execute timer if its the priority is appropriate
* @param timer pointer to lv_timer
* @return true: execute, false: not executed
*/
static bool lv_timer_exec(lv_timer_t * timer)
{
if(timer->paused) return false;
bool exec = false;
if(lv_timer_time_remaining(timer) == 0) {
timer->last_run = lv_tick_get();
timer_deleted = false;
timer_created = false;
if(timer->timer_cb) timer->timer_cb(timer);
LV_ASSERT_MEM_INTEGRITY();
/*Delete if it was a one shot lv_timer*/
if(timer_deleted == false) { /*The timer might be deleted by itself as well*/
if(timer->repeat_count > 0) {
timer->repeat_count--;
}
if(timer->repeat_count == 0) {
lv_timer_del(timer);
}
}
exec = true;
}
return exec;
}
/**
* Find out how much time remains before a timer must be run.
* @param timer pointer to lv_timer
* @return the time remaining, or 0 if it needs to be run again
*/
static uint32_t lv_timer_time_remaining(lv_timer_t * timer)
{
/*Check if at least 'period' time elapsed*/
uint32_t elp = lv_tick_elaps(timer->last_run);
if(elp >= timer->period)
return 0;
return timer->period - elp;
}

164
src/lv_misc/lv_timer.h Normal file
View File

@ -0,0 +1,164 @@
/**
* @file lv_timer.h
*/
#ifndef LV_TIMER_H
#define LV_TIMER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_conf_internal.h"
#include <stdint.h>
#include <stdbool.h>
#include "lv_mem.h"
#include "lv_ll.h"
/*********************
* DEFINES
*********************/
#ifndef LV_ATTRIBUTE_TIMER_HANDLER
#define LV_ATTRIBUTE_TIMER_HANDLER
#endif
#define LV_NO_TIMER_READY 0xFFFFFFFF
/**********************
* TYPEDEFS
**********************/
struct _lv_timer_t;
/**
* Tasks execute this type type of functions.
*/
typedef void (*lv_timer_cb_t)(struct _lv_timer_t *);
/**
* Descriptor of a lv_timer
*/
typedef struct _lv_timer_t {
uint32_t period; /**< How often the timer should run */
uint32_t last_run; /**< Last time the timer ran */
lv_timer_cb_t timer_cb; /**< Task function */
void * user_data; /**< Custom user data */
int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times */
uint32_t paused :1;
} lv_timer_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Init the lv_timer module
*/
void _lv_timer_core_init(void);
//! @cond Doxygen_Suppress
/**
* Call it periodically to handle lv_timers.
* @return time till it needs to be run next (in ms)
*/
LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void);
//! @endcond
/**
* Create an "empty" timer. It needs to initialized with at least
* `lv_timer_set_cb` and `lv_timer_set_period`
* @return pointer to the created timer
*/
lv_timer_t * lv_timer_create_basic(void);
/**
* Create a new lv_timer
* @param timer_xcb a callback to call periodically.
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
* the `func_name(object, callback, ...)` convention)
* @param period call period in ms unit
* @param user_data custom parameter
* @return pointer to the new timer
*/
lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * user_data);
/**
* Delete a lv_timer
* @param timer pointer to an lv_timer
*/
void lv_timer_del(lv_timer_t * timer);
/**
* Pause/resume a timer.
* @param timer pointer to an lv_timer
* @param pause true: pause the timer; false: resume
*/
void lv_timer_pause(lv_timer_t * timer, bool pause);
/**
* Set the callback the timer (the function to call periodically)
* @param timer pointer to a timer
* @param timer_cb the function to call periodically
*/
void lv_timer_set_cb(lv_timer_t * timer, lv_timer_cb_t timer_cb);
/**
* Set new period for a lv_timer
* @param timer pointer to a lv_timer
* @param period the new period
*/
void lv_timer_set_period(lv_timer_t * timer, uint32_t period);
/**
* Make a lv_timer ready. It will not wait its period.
* @param timer pointer to a lv_timer.
*/
void lv_timer_ready(lv_timer_t * timer);
/**
* Set the number of times a timer will repeat.
* @param timer pointer to a lv_timer.
* @param repeat_count -1 : infinity; 0 : stop ; n>0: residual times
*/
void lv_timer_set_repeat_count(lv_timer_t * timer, int32_t repeat_count);
/**
* Reset a lv_timer.
* It will be called the previously set period milliseconds later.
* @param timer pointer to a lv_timer.
*/
void lv_timer_reset(lv_timer_t * timer);
/**
* Enable or disable the whole lv_timer handling
* @param en: true: lv_timer handling is running, false: lv_timer handling is suspended
*/
void lv_timer_enable(bool en);
/**
* Get idle percentage
* @return the lv_timer idle in percentage
*/
uint8_t lv_timer_get_idle(void);
/**
* Iterate through the timers
* @param timer NULL to start iteration or the previous return value to get the next timer
* @return the next timer or NULL if there is no more timer
*/
lv_timer_t * lv_timer_get_next(lv_timer_t * timer);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@ -1,339 +0,0 @@
/**
* @file lv_tmr.c
*/
/*********************
* INCLUDES
*********************/
#include <stddef.h>
#include "lv_tmr.h"
#include "../lv_misc/lv_debug.h"
#include "../lv_hal/lv_hal_tick.h"
#include "lv_gc.h"
#if defined(LV_GC_INCLUDE)
#include LV_GC_INCLUDE
#endif /* LV_ENABLE_GC */
/*********************
* DEFINES
*********************/
#define IDLE_MEAS_PERIOD 500 /*[ms]*/
#define DEF_PERIOD 500
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static bool lv_tmr_exec(lv_tmr_t * tmr);
static uint32_t lv_tmr_time_remaining(lv_tmr_t * tmr);
/**********************
* STATIC VARIABLES
**********************/
static bool lv_tmr_run = false;
static uint8_t idle_last = 0;
static bool tmr_deleted;
static bool tmr_created;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Init the lv_tmr module
*/
void _lv_tmr_core_init(void)
{
_lv_ll_init(&LV_GC_ROOT(_lv_tmr_ll), sizeof(lv_tmr_t));
/*Initially enable the lv_tmr handling*/
lv_tmr_enable(true);
}
/**
* Call it periodically to handle lv_tmrs.
* @return the time after which it must be called again
*/
LV_ATTRIBUTE_TMR_HANDLER uint32_t lv_tmr_handler(void)
{
LV_LOG_TRACE("lv_tmr_handler started");
/*Avoid concurrent running of the tmr handler*/
static bool already_running = false;
if(already_running) return 1;
already_running = true;
static uint32_t idle_period_start = 0;
static uint32_t handler_start = 0;
static uint32_t busy_time = 0;
static uint32_t time_till_next;
if(lv_tmr_run == false) {
already_running = false; /*Release mutex*/
return 1;
}
handler_start = lv_tick_get();
/* Run all tmr from the highest to the lowest priority
* If a lower priority tmr is executed check tmr again from the highest priority
* but on the priority of executed tmrs don't run tmrs before the executed*/
lv_tmr_t * next;
bool end_flag;
do {
end_flag = true;
tmr_deleted = false;
tmr_created = false;
LV_GC_ROOT(_lv_tmr_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_tmr_ll));
while(LV_GC_ROOT(_lv_tmr_act)) {
/* The tmr might be deleted if it runs only once ('repeat_count = 1')
* So get next element until the current is surely valid*/
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_tmr_ll), LV_GC_ROOT(_lv_tmr_act));
if(lv_tmr_exec(LV_GC_ROOT(_lv_tmr_act))) {
if(!tmr_created && !tmr_deleted) {
end_flag = false;
break;
}
}
/*If a tmr was created or deleted then this or the next item might be corrupted*/
if(tmr_created || tmr_deleted) {
break;
}
LV_GC_ROOT(_lv_tmr_act) = next; /*Load the next tmr*/
}
} while(!end_flag);
busy_time += lv_tick_elaps(handler_start);
uint32_t idle_period_time = lv_tick_elaps(idle_period_start);
if(idle_period_time >= IDLE_MEAS_PERIOD) {
idle_last = (uint32_t)((uint32_t)busy_time * 100) / IDLE_MEAS_PERIOD; /*Calculate the busy percentage*/
idle_last = idle_last > 100 ? 0 : 100 - idle_last; /*But we need idle time*/
busy_time = 0;
idle_period_start = lv_tick_get();
}
time_till_next = LV_NO_TMR_READY;
next = _lv_ll_get_head(&LV_GC_ROOT(_lv_tmr_ll));
while(next) {
if(next->repeat_count) {
uint32_t delay = lv_tmr_time_remaining(next);
if(delay < time_till_next)
time_till_next = delay;
}
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_tmr_ll), next); /*Find the next tmr*/
}
already_running = false; /*Release the mutex*/
LV_LOG_TRACE("lv_tmr_handler ready");
return time_till_next;
}
/**
* Create an "empty" tmr. It needs to initialized with at least
* `lv_tmr_set_cb` and `lv_tmr_set_period`
* @return pointer to the created tmr
*/
lv_tmr_t * lv_tmr_create_basic(void)
{
lv_tmr_t * new_tmr = NULL;
new_tmr = _lv_ll_ins_head(&LV_GC_ROOT(_lv_tmr_ll));
LV_ASSERT_MEM(new_tmr);
if(new_tmr == NULL) return NULL;
new_tmr->period = DEF_PERIOD;
new_tmr->tmr_cb = NULL;
new_tmr->repeat_count = -1;
new_tmr->paused = 0;
new_tmr->last_run = lv_tick_get();
new_tmr->user_data = NULL;
tmr_created = true;
return new_tmr;
}
/**
* Create a new lv_tmr
* @param tmr_xcb a callback which is the tmr itself. It will be called periodically.
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
* the `func_name(object, callback, ...)` convention)
* @param period call period in ms unit
* @param user_data custom parameter
* @return pointer to the new tmr
*/
lv_tmr_t * lv_tmr_create(lv_tmr_cb_t tmr_xcb, uint32_t period, void * user_data)
{
lv_tmr_t * new_tmr = lv_tmr_create_basic();
LV_ASSERT_MEM(new_tmr);
if(new_tmr == NULL) return NULL;
lv_tmr_set_cb(new_tmr, tmr_xcb);
lv_tmr_set_period(new_tmr, period);
new_tmr->user_data = user_data;
return new_tmr;
}
/**
* Set the callback the tmr (the function to call periodically)
* @param tmr pointer to a tmr
* @param tmr_cb the function to call periodically
*/
void lv_tmr_set_cb(lv_tmr_t * tmr, lv_tmr_cb_t tmr_cb)
{
tmr->tmr_cb = tmr_cb;
}
/**
* Delete a lv_tmr
* @param tmr pointer to tmr created by tmr
*/
void lv_tmr_del(lv_tmr_t * tmr)
{
_lv_ll_remove(&LV_GC_ROOT(_lv_tmr_ll), tmr);
tmr_deleted = true;
lv_mem_free(tmr);
}
/**
* Pause/resume a timer.
* @param tmr pointer to an lv_tmr
* @param pause true: pause the timer; false: resume
*/
void lv_tmr_pause(lv_tmr_t * tmr, bool pause)
{
tmr->paused = pause;
}
/**
* Set new period for a lv_tmr
* @param tmr pointer to a lv_tmr
* @param period the new period
*/
void lv_tmr_set_period(lv_tmr_t * tmr, uint32_t period)
{
tmr->period = period;
}
/**
* Make a lv_tmr ready. It will not wait its period.
* @param tmr pointer to a lv_tmr.
*/
void lv_tmr_ready(lv_tmr_t * tmr)
{
tmr->last_run = lv_tick_get() - tmr->period - 1;
}
/**
* Set the number of times a tmr will repeat.
* @param tmr pointer to a lv_tmr.
* @param repeat_count -1 : infinity; 0 : stop ; n >0: residual times
*/
void lv_tmr_set_repeat_count(lv_tmr_t * tmr, int32_t repeat_count)
{
tmr->repeat_count = repeat_count;
}
/**
* Reset a lv_tmr.
* It will be called the previously set period milliseconds later.
* @param tmr pointer to a lv_tmr.
*/
void lv_tmr_reset(lv_tmr_t * tmr)
{
tmr->last_run = lv_tick_get();
}
/**
* Enable or disable the whole lv_tmr handling
* @param en: true: lv_tmr handling is running, false: lv_tmr handling is suspended
*/
void lv_tmr_enable(bool en)
{
lv_tmr_run = en;
}
/**
* Get idle percentage
* @return the lv_tmr idle in percentage
*/
uint8_t lv_tmr_get_idle(void)
{
return idle_last;
}
/**
* Iterate through the tmrs
* @param tmr NULL to start iteration or the previous return value to get the next tmr
* @return the next tmr or NULL if there is no more tmr
*/
lv_tmr_t * lv_tmr_get_next(lv_tmr_t * tmr)
{
if(tmr == NULL) return _lv_ll_get_head(&LV_GC_ROOT(_lv_tmr_ll));
else return _lv_ll_get_next(&LV_GC_ROOT(_lv_tmr_ll), tmr);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Execute tmr if its the priority is appropriate
* @param tmr pointer to lv_tmr
* @return true: execute, false: not executed
*/
static bool lv_tmr_exec(lv_tmr_t * tmr)
{
if(tmr->paused) return false;
bool exec = false;
if(lv_tmr_time_remaining(tmr) == 0) {
tmr->last_run = lv_tick_get();
tmr_deleted = false;
tmr_created = false;
if(tmr->tmr_cb) tmr->tmr_cb(tmr);
LV_ASSERT_MEM_INTEGRITY();
/*Delete if it was a one shot lv_tmr*/
if(tmr_deleted == false) { /*The tmr might be deleted by itself as well*/
if(tmr->repeat_count > 0) {
tmr->repeat_count--;
}
if(tmr->repeat_count == 0) {
lv_tmr_del(tmr);
}
}
exec = true;
}
return exec;
}
/**
* Find out how much time remains before a tmr must be run.
* @param tmr pointer to lv_tmr
* @return the time remaining, or 0 if it needs to be run again
*/
static uint32_t lv_tmr_time_remaining(lv_tmr_t * tmr)
{
/*Check if at least 'period' time elapsed*/
uint32_t elp = lv_tick_elaps(tmr->last_run);
if(elp >= tmr->period)
return 0;
return tmr->period - elp;
}

View File

@ -1,164 +0,0 @@
/**
* @file lv_tmr.h
*/
#ifndef LV_TMR_H
#define LV_TMR_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_conf_internal.h"
#include <stdint.h>
#include <stdbool.h>
#include "lv_mem.h"
#include "lv_ll.h"
/*********************
* DEFINES
*********************/
#ifndef LV_ATTRIBUTE_TMR_HANDLER
#define LV_ATTRIBUTE_TMR_HANDLER
#endif
#define LV_NO_TMR_READY 0xFFFFFFFF
/**********************
* TYPEDEFS
**********************/
struct _lv_tmr_t;
/**
* Tasks execute this type type of functions.
*/
typedef void (*lv_tmr_cb_t)(struct _lv_tmr_t *);
/**
* Descriptor of a lv_tmr
*/
typedef struct _lv_tmr_t {
uint32_t period; /**< How often the tmr should run */
uint32_t last_run; /**< Last time the tmr ran */
lv_tmr_cb_t tmr_cb; /**< Task function */
void * user_data; /**< Custom user data */
int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times */
uint32_t paused :1;
} lv_tmr_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Init the lv_tmr module
*/
void _lv_tmr_core_init(void);
//! @cond Doxygen_Suppress
/**
* Call it periodically to handle lv_tmrs.
* @return time till it needs to be run next (in ms)
*/
LV_ATTRIBUTE_TMR_HANDLER uint32_t lv_tmr_handler(void);
//! @endcond
/**
* Create an "empty" tmr. It needs to initialized with at least
* `lv_tmr_set_cb` and `lv_tmr_set_period`
* @return pointer to the created tmr
*/
lv_tmr_t * lv_tmr_create_basic(void);
/**
* Create a new lv_tmr
* @param tmr_xcb a callback to call periodically.
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
* the `func_name(object, callback, ...)` convention)
* @param period call period in ms unit
* @param user_data custom parameter
* @return pointer to the new timer
*/
lv_tmr_t * lv_tmr_create(lv_tmr_cb_t tmr_xcb, uint32_t period, void * user_data);
/**
* Delete a lv_tmr
* @param tmr pointer to an lv_tmr
*/
void lv_tmr_del(lv_tmr_t * tmr);
/**
* Pause/resume a timer.
* @param tmr pointer to an lv_tmr
* @param pause true: pause the timer; false: resume
*/
void lv_tmr_pause(lv_tmr_t * tmr, bool pause);
/**
* Set the callback the tmr (the function to call periodically)
* @param tmr pointer to a tmr
* @param tmr_cb the function to call periodically
*/
void lv_tmr_set_cb(lv_tmr_t * tmr, lv_tmr_cb_t tmr_cb);
/**
* Set new period for a lv_tmr
* @param tmr pointer to a lv_tmr
* @param period the new period
*/
void lv_tmr_set_period(lv_tmr_t * tmr, uint32_t period);
/**
* Make a lv_tmr ready. It will not wait its period.
* @param tmr pointer to a lv_tmr.
*/
void lv_tmr_ready(lv_tmr_t * tmr);
/**
* Set the number of times a tmr will repeat.
* @param tmr pointer to a lv_tmr.
* @param repeat_count -1 : infinity; 0 : stop ; n>0: residual times
*/
void lv_tmr_set_repeat_count(lv_tmr_t * tmr, int32_t repeat_count);
/**
* Reset a lv_tmr.
* It will be called the previously set period milliseconds later.
* @param tmr pointer to a lv_tmr.
*/
void lv_tmr_reset(lv_tmr_t * tmr);
/**
* Enable or disable the whole lv_tmr handling
* @param en: true: lv_tmr handling is running, false: lv_tmr handling is suspended
*/
void lv_tmr_enable(bool en);
/**
* Get idle percentage
* @return the lv_tmr idle in percentage
*/
uint8_t lv_tmr_get_idle(void);
/**
* Iterate through the tmrs
* @param tmr NULL to start iteration or the previous return value to get the next tmr
* @return the next tmr or NULL if there is no more tmr
*/
lv_tmr_t * lv_tmr_get_next(lv_tmr_t * tmr);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif