diff --git a/src/lv_api_map.h b/src/lv_api_map.h index b425799be..782758b13 100644 --- a/src/lv_api_map.h +++ b/src/lv_api_map.h @@ -27,6 +27,11 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ +static LV_ATTRIBUTE_TMR_HANDLER uint32_t lv_task_handler(void) +{ + return lv_tmr_handler(); +} + /********************** * MACROS **********************/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 0fc2a73b6..83e778391 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -632,11 +632,11 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */ #endif /* Define a custom attribute to `lv_task_handler` function */ -#ifndef LV_ATTRIBUTE_TASK_HANDLER -# ifdef CONFIG_LV_ATTRIBUTE_TASK_HANDLER -# define LV_ATTRIBUTE_TASK_HANDLER CONFIG_LV_ATTRIBUTE_TASK_HANDLER +#ifndef LV_ATTRIBUTE_TMR_HANDLER +# ifdef CONFIG_LV_ATTRIBUTE_TMR_HANDLER +# define LV_ATTRIBUTE_TMR_HANDLER CONFIG_LV_ATTRIBUTE_TMR_HANDLER # else -# define LV_ATTRIBUTE_TASK_HANDLER +# define LV_ATTRIBUTE_TMR_HANDLER # endif #endif diff --git a/src/lv_core/lv_disp.c b/src/lv_core/lv_disp.c index ea4a87003..a36edc0c4 100644 --- a/src/lv_core/lv_disp.c +++ b/src/lv_core/lv_disp.c @@ -367,7 +367,7 @@ void lv_disp_clean_dcache(lv_disp_t * disp) * @param disp pointer to a display * @return pointer to the display refresher task. (NULL on error) */ -lv_task_t * _lv_disp_get_refr_task(lv_disp_t * disp) +lv_tmr_t * _lv_disp_get_refr_task(lv_disp_t * disp) { if(!disp) disp = lv_disp_get_default(); if(!disp) { diff --git a/src/lv_core/lv_disp.h b/src/lv_core/lv_disp.h index 00a9de8db..b986abdd0 100644 --- a/src/lv_core/lv_disp.h +++ b/src/lv_core/lv_disp.h @@ -145,7 +145,7 @@ void lv_disp_clean_dcache(lv_disp_t * disp); * @param disp pointer to a display * @return pointer to the display refresher task. (NULL on error) */ -lv_task_t * _lv_disp_get_refr_task(lv_disp_t * disp); +lv_tmr_t * _lv_disp_get_refr_task(lv_disp_t * disp); /*------------------------------------------------ * To improve backward compatibility diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index 272a81656..bd2843e3b 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -14,7 +14,7 @@ #include "lv_refr.h" #include "../lv_hal/lv_hal_tick.h" -#include "../lv_misc/lv_task.h" +#include "../lv_misc/lv_tmr.h" #include "../lv_misc/lv_math.h" /********************* @@ -70,7 +70,7 @@ void _lv_indev_init(void) * Called periodically to read the input devices * @param param pointer to and input device to read */ -void _lv_indev_read_task(lv_task_t * task) +void _lv_indev_read_task(lv_tmr_t * task) { 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 * @return pointer to the indev read refresher task. (NULL on error) */ -lv_task_t * lv_indev_get_read_task(lv_disp_t * indev) +lv_tmr_t * lv_indev_get_read_task(lv_disp_t * indev) { if(!indev) { LV_LOG_WARN("lv_indev_get_read_task: indev was NULL"); diff --git a/src/lv_core/lv_indev.h b/src/lv_core/lv_indev.h index 53c5b8451..dd7824e23 100644 --- a/src/lv_core/lv_indev.h +++ b/src/lv_core/lv_indev.h @@ -38,7 +38,7 @@ void _lv_indev_init(void); * Called periodically to read the input devices * @param task pointer to the task itself */ -void _lv_indev_read_task(lv_task_t * task); +void _lv_indev_read_task(lv_tmr_t * task); /** * 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 * @return pointer to the indev read refresher task. (NULL on error) */ -lv_task_t * lv_indev_get_read_task(lv_disp_t * indev); +lv_tmr_t * lv_indev_get_read_task(lv_disp_t * indev); /********************** * MACROS diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index e413edcb7..b7c938f24 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -15,7 +15,7 @@ #include "../lv_themes/lv_theme.h" #include "../lv_draw/lv_draw.h" #include "../lv_misc/lv_anim.h" -#include "../lv_misc/lv_task.h" +#include "../lv_misc/lv_tmr.h" #include "../lv_misc/lv_async.h" #include "../lv_misc/lv_fs.h" #include "../lv_misc/lv_gc.h" @@ -100,7 +100,7 @@ void lv_init(void) /*Initialize the lv_misc modules*/ _lv_mem_init(); - _lv_task_core_init(); + _lv_tmr_core_init(); #if LV_USE_FILESYSTEM _lv_fs_init(); diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index cb554fcf9..d9503e2d0 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -11,7 +11,7 @@ #include "lv_disp.h" #include "../lv_hal/lv_hal_tick.h" #include "../lv_hal/lv_hal_disp.h" -#include "../lv_misc/lv_task.h" +#include "../lv_misc/lv_tmr.h" #include "../lv_misc/lv_mem.h" #include "../lv_misc/lv_math.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); } disp->inv_p++; - lv_task_set_prio(disp->refr_task, LV_REFR_TASK_PRIO); + lv_tmr_pause(disp->refr_task, false); } } @@ -172,20 +172,20 @@ void _lv_refr_set_disp_refreshing(lv_disp_t * disp) * Called periodically to handle the refreshing * @param task pointer to the task itself */ -void _lv_disp_refr_task(lv_task_t * task) +void _lv_disp_refr_task(lv_tmr_t * tmr) { LV_LOG_TRACE("lv_refr_task: started"); uint32_t start = lv_tick_get(); uint32_t elaps = 0; - disp_refr = task->user_data; + disp_refr = tmr->user_data; #if LV_USE_PERF_MONITOR == 0 /* Ensure the task does not run again automatically. * This is done before refreshing in case refreshing invalidates something else. */ - lv_task_set_prio(task, LV_TASK_PRIO_OFF); + lv_tmr_pause(tmr, true); #endif /*Do nothing if there is no active screen*/ diff --git a/src/lv_core/lv_refr.h b/src/lv_core/lv_refr.h index 7fa76e42e..ca0c7bda8 100644 --- a/src/lv_core/lv_refr.h +++ b/src/lv_core/lv_refr.h @@ -82,7 +82,7 @@ void _lv_refr_set_disp_refreshing(lv_disp_t * disp); * Called periodically to handle the refreshing * @param task pointer to the task itself */ -void _lv_disp_refr_task(lv_task_t * task); +void _lv_disp_refr_task(lv_tmr_t * task); /********************** * STATIC FUNCTIONS diff --git a/src/lv_hal/lv_hal_disp.c b/src/lv_hal/lv_hal_disp.c index fc8ded363..6e0aff84d 100644 --- a/src/lv_hal/lv_hal_disp.c +++ b/src/lv_hal/lv_hal_disp.c @@ -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 new display*/ /*Create a refresh task*/ - disp->refr_task = lv_task_create(_lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_REFR_TASK_PRIO, disp); + disp->refr_task = lv_tmr_create(_lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, disp); LV_ASSERT_MEM(disp->refr_task); 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*/ - lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/ + lv_tmr_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*/ if(lv_disp_is_true_double_buf(disp) && disp->driver.set_px_cb) { diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h index 7a1eef6b0..ebc5721ef 100644 --- a/src/lv_hal/lv_hal_disp.h +++ b/src/lv_hal/lv_hal_disp.h @@ -21,7 +21,7 @@ extern "C" { #include "../lv_misc/lv_color.h" #include "../lv_misc/lv_area.h" #include "../lv_misc/lv_ll.h" -#include "../lv_misc/lv_task.h" +#include "../lv_misc/lv_tmr.h" /********************* * DEFINES @@ -149,7 +149,7 @@ typedef struct _disp_t { lv_disp_drv_t driver; /**< A task which periodically checks the dirty areas and refreshes them*/ - lv_task_t * refr_task; + lv_tmr_t * refr_task; /** Screens of the display*/ lv_ll_t scr_ll; diff --git a/src/lv_hal/lv_hal_indev.c b/src/lv_hal/lv_hal_indev.c index c0f2f4835..f57862b3b 100644 --- a/src/lv_hal/lv_hal_indev.c +++ b/src/lv_hal/lv_hal_indev.c @@ -92,7 +92,7 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver) indev->group = NULL; indev->btn_points = NULL; - indev->driver.read_task = lv_task_create(_lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_HIGH, indev); + indev->driver.read_task = lv_tmr_create(_lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, indev); return indev; } diff --git a/src/lv_hal/lv_hal_indev.h b/src/lv_hal/lv_hal_indev.h index 43fcd33bc..2f9e809de 100644 --- a/src/lv_hal/lv_hal_indev.h +++ b/src/lv_hal/lv_hal_indev.h @@ -20,7 +20,7 @@ extern "C" { #include #include #include "../lv_misc/lv_area.h" -#include "../lv_misc/lv_task.h" +#include "../lv_misc/lv_tmr.h" /********************* * DEFINES @@ -100,7 +100,7 @@ typedef struct _lv_indev_drv_t { struct _disp_t * disp; /**< Task to read the periodically read the input device*/ - lv_task_t * read_task; + lv_tmr_t * read_task; /**< Number of pixels to slide before actually drag the object*/ uint8_t scroll_limit; diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index a19c17000..b9bafcf00 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -13,7 +13,7 @@ #include #include "../lv_misc/lv_debug.h" #include "../lv_hal/lv_hal_tick.h" -#include "lv_task.h" +#include "lv_tmr.h" #include "lv_math.h" #include "lv_gc.h" @@ -26,7 +26,6 @@ *********************/ #define LV_ANIM_RESOLUTION 1024 #define LV_ANIM_RES_SHIFT 10 -#define LV_ANIM_TASK_PRIO LV_TASK_PRIO_HIGH /********************** * TYPEDEFS @@ -35,7 +34,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static void anim_task(lv_task_t * param); +static void anim_task(lv_tmr_t * param); static void anim_mark_list_change(void); static bool anim_ready_handler(lv_anim_t * a); @@ -44,7 +43,7 @@ static bool anim_ready_handler(lv_anim_t * a); **********************/ static uint32_t last_task_run; static bool anim_list_changed; -static lv_task_t * _lv_anim_task; +static lv_tmr_t * _lv_anim_tmr; const lv_anim_path_t lv_anim_path_def = {.cb = lv_anim_path_linear}; /********************** @@ -62,7 +61,7 @@ void _lv_anim_core_init(void) { _lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t)); last_task_run = lv_tick_get(); - _lv_anim_task = lv_task_create(anim_task, LV_DISP_DEF_REFR_PERIOD, LV_ANIM_TASK_PRIO, NULL); + _lv_anim_tmr = lv_tmr_create(anim_task, LV_DISP_DEF_REFR_PERIOD, NULL); anim_mark_list_change(); /*Turn off the animation task*/ anim_list_changed = false; /*The list has not actually changed*/ } @@ -439,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. * @param param unused */ -static void anim_task(lv_task_t * param) +static void anim_task(lv_tmr_t * param) { (void)param; @@ -555,8 +554,8 @@ static void anim_mark_list_change(void) { anim_list_changed = true; if(_lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll)) == NULL) - lv_task_set_prio(_lv_anim_task, LV_TASK_PRIO_OFF); + lv_tmr_pause(_lv_anim_tmr, true); else - lv_task_set_prio(_lv_anim_task, LV_ANIM_TASK_PRIO); + lv_tmr_pause(_lv_anim_tmr, false); } #endif diff --git a/src/lv_misc/lv_async.c b/src/lv_misc/lv_async.c index 4336ff09a..f48e07155 100644 --- a/src/lv_misc/lv_async.c +++ b/src/lv_misc/lv_async.c @@ -21,7 +21,7 @@ * STATIC PROTOTYPES **********************/ -static void lv_async_task_cb(lv_task_t * task); +static void lv_async_task_cb(lv_tmr_t * task); /********************** * 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 */ /* Use highest priority so that it will run before a refresh */ - lv_task_t * task = lv_task_create(lv_async_task_cb, 0, LV_TASK_PRIO_HIGHEST, info); + lv_tmr_t * task = lv_tmr_create(lv_async_task_cb, 0, info); if(task == NULL) { 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 */ task->user_data = info; - lv_task_set_repeat_count(task, 1); + lv_tmr_set_repeat_count(task, 1); 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 void lv_async_task_cb(lv_task_t * task) +static void lv_async_task_cb(lv_tmr_t * task) { lv_async_info_t * info = (lv_async_info_t *)task->user_data; diff --git a/src/lv_misc/lv_async.h b/src/lv_misc/lv_async.h index 34ad7999e..8227be8f4 100644 --- a/src/lv_misc/lv_async.h +++ b/src/lv_misc/lv_async.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "lv_task.h" +#include "lv_tmr.h" #include "lv_types.h" /********************* diff --git a/src/lv_misc/lv_gc.h b/src/lv_misc/lv_gc.h index c59ca5704..0ecdddf8b 100644 --- a/src/lv_misc/lv_gc.h +++ b/src/lv_misc/lv_gc.h @@ -17,7 +17,7 @@ extern "C" { #include #include "lv_mem.h" #include "lv_ll.h" -#include "lv_task.h" +#include "lv_tmr.h" #include "../lv_draw/lv_img_cache.h" #include "../lv_draw/lv_draw_mask.h" @@ -26,7 +26,7 @@ extern "C" { *********************/ #define LV_ITERATE_ROOTS(f) \ - f(lv_ll_t, _lv_task_ll) /*Linked list to store the lv_tasks*/ \ + f(lv_ll_t, _lv_tmr_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_indev_ll) /*Linked list of screens*/ \ f(lv_ll_t, _lv_drv_ll) \ @@ -36,11 +36,10 @@ extern "C" { f(lv_ll_t, _lv_img_defoder_ll) \ f(lv_ll_t, _lv_obj_style_trans_ll) \ f(lv_img_cache_entry_t*, _lv_img_cache_array) \ - f(lv_task_t*, _lv_task_act) \ + f(lv_tmr_t*, _lv_tmr_act) \ f(lv_mem_buf_arr_t , _lv_mem_buf) \ f(_lv_draw_mask_saved_arr_t , _lv_draw_mask_list) \ f(void * , _lv_theme_material_styles) \ - f(void * , _lv_theme_template_styles) \ f(void * , _lv_theme_mono_styles) \ f(void * , _lv_theme_empty_styles) \ f(uint8_t *, _lv_font_decompr_buf) \ diff --git a/src/lv_misc/lv_task.c b/src/lv_misc/lv_task.c deleted file mode 100644 index 954eba29f..000000000 --- a/src/lv_misc/lv_task.c +++ /dev/null @@ -1,439 +0,0 @@ -/** - * @file lv_task.c - * An 'lv_task' is a void (*fp) (void* param) type function which will be called periodically. - * A priority (5 levels + disable) can be assigned to lv_tasks. - */ - -/********************* - * INCLUDES - *********************/ -#include -#include "lv_task.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_PRIO LV_TASK_PRIO_MID -#define DEF_PERIOD 500 - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static bool lv_task_exec(lv_task_t * task); -static uint32_t lv_task_time_remaining(lv_task_t * task); - -/********************** - * STATIC VARIABLES - **********************/ -static bool lv_task_run = false; -static uint8_t idle_last = 0; -static bool task_deleted; -static bool task_list_changed; -static bool task_created; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -/** - * Init the lv_task module - */ -void _lv_task_core_init(void) -{ - _lv_ll_init(&LV_GC_ROOT(_lv_task_ll), sizeof(lv_task_t)); - - task_list_changed = false; - /*Initially enable the lv_task handling*/ - lv_task_enable(true); -} - -/** - * Call it periodically to handle lv_tasks. - * @return the time after which it must be called again - */ -LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void) -{ - - - LV_LOG_TRACE("lv_task_handler started"); - - /*Avoid concurrent running of the task 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_task_run == false) { - already_running = false; /*Release mutex*/ - return 1; - } - - handler_start = lv_tick_get(); - - /* Run all task from the highest to the lowest priority - * If a lower priority task is executed check task again from the highest priority - * but on the priority of executed tasks don't run tasks before the executed*/ - lv_task_t * task_interrupter = NULL; - lv_task_t * next; - bool end_flag; - do { - end_flag = true; - task_deleted = false; - task_created = false; - LV_GC_ROOT(_lv_task_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll)); - while(LV_GC_ROOT(_lv_task_act)) { - /* The task might be deleted if it runs only once ('once = 1') - * So get next element until the current is surely valid*/ - next = _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), LV_GC_ROOT(_lv_task_act)); - - /*We reach priority of the turned off task. There is nothing more to do.*/ - if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio == LV_TASK_PRIO_OFF) { - break; - } - - /*Here is the interrupter task. Don't execute it again.*/ - if(LV_GC_ROOT(_lv_task_act) == task_interrupter) { - task_interrupter = NULL; /*From this point only task after the interrupter comes, so - the interrupter is not interesting anymore*/ - LV_GC_ROOT(_lv_task_act) = next; - continue; /*Load the next task*/ - } - - /*Just try to run the tasks with highest priority.*/ - if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio == LV_TASK_PRIO_HIGHEST) { - lv_task_exec(LV_GC_ROOT(_lv_task_act)); - } - /*Tasks with higher priority than the interrupted shall be run in every case*/ - else if(task_interrupter) { - if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio > task_interrupter->prio) { - if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) { - if(!task_created && !task_deleted) { - /*Check all tasks again from the highest priority */ - task_interrupter = LV_GC_ROOT(_lv_task_act); - end_flag = false; - break; - } - } - } - } - /* It is no interrupter task or we already reached it earlier. - * Just run the remaining tasks*/ - else { - if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) { - if(!task_created && !task_deleted) { - task_interrupter = LV_GC_ROOT(_lv_task_act); /*Check all tasks again from the highest priority */ - end_flag = false; - break; - } - } - } - - /*If a task was created or deleted then this or the next item might be corrupted*/ - if(task_created || task_deleted) { - task_interrupter = NULL; - break; - } - - if(task_list_changed) { - task_interrupter = NULL; - end_flag = false; - task_list_changed = false; - break; - } - - LV_GC_ROOT(_lv_task_act) = next; /*Load the next task*/ - } - } 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_TASK_READY; - next = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll)); - while(next) { - if(next->prio != LV_TASK_PRIO_OFF) { - uint32_t delay = lv_task_time_remaining(next); - if(delay < time_till_next) - time_till_next = delay; - } - - next = _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), next); /*Find the next task*/ - } - - already_running = false; /*Release the mutex*/ - - LV_LOG_TRACE("lv_task_handler ready"); - return time_till_next; -} -/** - * Create an "empty" task. It needs to initialized with at least - * `lv_task_set_cb` and `lv_task_set_period` - * @return pointer to the created task - */ -lv_task_t * lv_task_create_basic(void) -{ - lv_task_t * new_task = NULL; - lv_task_t * tmp; - - /*Create task lists in order of priority from high to low*/ - tmp = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll)); - - /*It's the first task*/ - if(NULL == tmp) { - new_task = _lv_ll_ins_head(&LV_GC_ROOT(_lv_task_ll)); - LV_ASSERT_MEM(new_task); - if(new_task == NULL) return NULL; - } - /*Insert the new task to proper place according to its priority*/ - else { - do { - if(tmp->prio <= DEF_PRIO) { - new_task = _lv_ll_ins_prev(&LV_GC_ROOT(_lv_task_ll), tmp); - LV_ASSERT_MEM(new_task); - if(new_task == NULL) return NULL; - break; - } - tmp = _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), tmp); - } while(tmp != NULL); - - /*Only too high priority tasks were found. Add the task to the end*/ - if(tmp == NULL) { - new_task = _lv_ll_ins_tail(&LV_GC_ROOT(_lv_task_ll)); - LV_ASSERT_MEM(new_task); - if(new_task == NULL) return NULL; - } - } - task_list_changed = true; - - new_task->period = DEF_PERIOD; - new_task->task_cb = NULL; - new_task->prio = DEF_PRIO; - - new_task->repeat_count = -1; - new_task->last_run = lv_tick_get(); - - new_task->user_data = NULL; - - task_created = true; - - return new_task; -} - -/** - * Create a new lv_task - * @param task_xcb a callback which is the task 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 prio priority of the task (LV_TASK_PRIO_OFF means the task is stopped) - * @param user_data custom parameter - * @return pointer to the new task - */ -lv_task_t * lv_task_create(lv_task_cb_t task_xcb, uint32_t period, lv_task_prio_t prio, void * user_data) -{ - lv_task_t * new_task = lv_task_create_basic(); - LV_ASSERT_MEM(new_task); - if(new_task == NULL) return NULL; - - lv_task_set_cb(new_task, task_xcb); - lv_task_set_period(new_task, period); - lv_task_set_prio(new_task, prio); - new_task->user_data = user_data; - - return new_task; -} - -/** - * Set the callback the task (the function to call periodically) - * @param task pointer to a task - * @param task_cb the function to call periodically - */ -void lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb) -{ - task->task_cb = task_cb; -} - -/** - * Delete a lv_task - * @param task pointer to task created by task - */ -void lv_task_del(lv_task_t * task) -{ - _lv_ll_remove(&LV_GC_ROOT(_lv_task_ll), task); - task_list_changed = true; - - lv_mem_free(task); - - if(LV_GC_ROOT(_lv_task_act) == task) task_deleted = true; /*The active task was deleted*/ -} - -/** - * Set new priority for a lv_task - * @param task pointer to a lv_task - * @param prio the new priority - */ -void lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio) -{ - if(task->prio == prio) return; - - /*Find the tasks with new priority*/ - lv_task_t * i; - _LV_LL_READ(&LV_GC_ROOT(_lv_task_ll), i) { - if(i->prio <= prio) { - if(i != task) _lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, i); - break; - } - } - - /*There was no such a low priority so far then add the node to the tail*/ - if(i == NULL) { - _lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, NULL); - } - task_list_changed = true; - - task->prio = prio; -} - -/** - * Set new period for a lv_task - * @param task pointer to a lv_task - * @param period the new period - */ -void lv_task_set_period(lv_task_t * task, uint32_t period) -{ - task->period = period; -} - -/** - * Make a lv_task ready. It will not wait its period. - * @param task pointer to a lv_task. - */ -void lv_task_ready(lv_task_t * task) -{ - task->last_run = lv_tick_get() - task->period - 1; -} - -/** - * Set the number of times a task will repeat. - * @param task pointer to a lv_task. - * @param repeat_count -1 : infinity; 0 : stop ; n>0: residual times - */ -void lv_task_set_repeat_count(lv_task_t * task, int32_t repeat_count) -{ - task->repeat_count = repeat_count; -} - -/** - * Reset a lv_task. - * It will be called the previously set period milliseconds later. - * @param task pointer to a lv_task. - */ -void lv_task_reset(lv_task_t * task) -{ - task->last_run = lv_tick_get(); -} - -/** - * Enable or disable the whole lv_task handling - * @param en: true: lv_task handling is running, false: lv_task handling is suspended - */ -void lv_task_enable(bool en) -{ - lv_task_run = en; -} - -/** - * Get idle percentage - * @return the lv_task idle in percentage - */ -uint8_t lv_task_get_idle(void) -{ - return idle_last; -} - -/** - * Iterate through the tasks - * @param task NULL to start iteration or the previous return value to get the next task - * @return the next task or NULL if there is no more task - */ -lv_task_t * lv_task_get_next(lv_task_t * task) -{ - if(task == NULL) return _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll)); - else return _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), task); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -/** - * Execute task if its the priority is appropriate - * @param task pointer to lv_task - * @return true: execute, false: not executed - */ -static bool lv_task_exec(lv_task_t * task) -{ - bool exec = false; - - if(lv_task_time_remaining(task) == 0) { - task->last_run = lv_tick_get(); - task_deleted = false; - task_created = false; - if(task->task_cb) task->task_cb(task); - LV_ASSERT_MEM_INTEGRITY(); - - /*Delete if it was a one shot lv_task*/ - if(task_deleted == false) { /*The task might be deleted by itself as well*/ - if(task->repeat_count > 0) { - task->repeat_count--; - } - if(task->repeat_count == 0) { - lv_task_del(task); - } - } - exec = true; - } - - return exec; -} - -/** - * Find out how much time remains before a task must be run. - * @param task pointer to lv_task - * @return the time remaining, or 0 if it needs to be run again - */ -static uint32_t lv_task_time_remaining(lv_task_t * task) -{ - /*Check if at least 'period' time elapsed*/ - uint32_t elp = lv_tick_elaps(task->last_run); - if(elp >= task->period) - return 0; - return task->period - elp; -} diff --git a/src/lv_misc/lv_task.h b/src/lv_misc/lv_task.h deleted file mode 100644 index d3dfc4adb..000000000 --- a/src/lv_misc/lv_task.h +++ /dev/null @@ -1,183 +0,0 @@ -/** - * @file lv_task.c - * An 'lv_task' is a void (*fp) (void* param) type function which will be called periodically. - * A priority (5 levels + disable) can be assigned to lv_tasks. - */ - -#ifndef LV_TASK_H -#define LV_TASK_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../lv_conf_internal.h" - -#include -#include -#include "lv_mem.h" -#include "lv_ll.h" - -/********************* - * DEFINES - *********************/ -#ifndef LV_ATTRIBUTE_TASK_HANDLER -#define LV_ATTRIBUTE_TASK_HANDLER -#endif - -#define LV_NO_TASK_READY 0xFFFFFFFF -/********************** - * TYPEDEFS - **********************/ - -struct _lv_task_t; - -/** - * Tasks execute this type type of functions. - */ -typedef void (*lv_task_cb_t)(struct _lv_task_t *); - -/** - * Possible priorities for lv_tasks - */ -enum { - LV_TASK_PRIO_OFF = 0, - LV_TASK_PRIO_LOWEST, - LV_TASK_PRIO_LOW, - LV_TASK_PRIO_MID, - LV_TASK_PRIO_HIGH, - LV_TASK_PRIO_HIGHEST, - _LV_TASK_PRIO_NUM, -}; -typedef uint8_t lv_task_prio_t; - -/** - * Descriptor of a lv_task - */ -typedef struct _lv_task_t { - uint32_t period; /**< How often the task should run */ - uint32_t last_run; /**< Last time the task ran */ - lv_task_cb_t task_cb; /**< Task function */ - - void * user_data; /**< Custom user data */ - - int32_t repeat_count; /**< 1: Task times; -1 : infinity; 0 : stop ; n>0: residual times */ - uint8_t prio : 3; /**< Task priority */ -} lv_task_t; - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * Init the lv_task module - */ -void _lv_task_core_init(void); - -//! @cond Doxygen_Suppress - -/** - * Call it periodically to handle lv_tasks. - * @return time till it needs to be run next (in ms) - */ -LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void); - -//! @endcond - -/** - * Create an "empty" task. It needs to initialized with at least - * `lv_task_set_cb` and `lv_task_set_period` - * @return pointer to the created task - */ -lv_task_t * lv_task_create_basic(void); - -/** - * Create a new lv_task - * @param task_xcb a callback which is the task 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 prio priority of the task (LV_TASK_PRIO_OFF means the task is stopped) - * @param user_data custom parameter - * @return pointer to the new task - */ -lv_task_t * lv_task_create(lv_task_cb_t task_xcb, uint32_t period, lv_task_prio_t prio, void * user_data); - -/** - * Delete a lv_task - * @param task pointer to task_cb created by task - */ -void lv_task_del(lv_task_t * task); - -/** - * Set the callback the task (the function to call periodically) - * @param task pointer to a task - * @param task_cb the function to call periodically - */ -void lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb); - -/** - * Set new priority for a lv_task - * @param task pointer to a lv_task - * @param prio the new priority - */ -void lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio); - -/** - * Set new period for a lv_task - * @param task pointer to a lv_task - * @param period the new period - */ -void lv_task_set_period(lv_task_t * task, uint32_t period); - -/** - * Make a lv_task ready. It will not wait its period. - * @param task pointer to a lv_task. - */ -void lv_task_ready(lv_task_t * task); - -/** - * Set the number of times a task will repeat. - * @param task pointer to a lv_task. - * @param repeat_count -1 : infinity; 0 : stop ; n>0: residual times - */ -void lv_task_set_repeat_count(lv_task_t * task, int32_t repeat_count); - -/** - * Reset a lv_task. - * It will be called the previously set period milliseconds later. - * @param task pointer to a lv_task. - */ -void lv_task_reset(lv_task_t * task); - -/** - * Enable or disable the whole lv_task handling - * @param en: true: lv_task handling is running, false: lv_task handling is suspended - */ -void lv_task_enable(bool en); - -/** - * Get idle percentage - * @return the lv_task idle in percentage - */ -uint8_t lv_task_get_idle(void); - -/** - * Iterate through the tasks - * @param task NULL to start iteration or the previous return value to get the next task - * @return the next task or NULL if there is no more task - */ -lv_task_t * lv_task_get_next(lv_task_t * task); - -/********************** - * MACROS - **********************/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/lv_misc/lv_tmr.c b/src/lv_misc/lv_tmr.c new file mode 100644 index 000000000..7cf97f4a7 --- /dev/null +++ b/src/lv_misc/lv_tmr.c @@ -0,0 +1,340 @@ +/** + * @file lv_tmr.c + */ + +/********************* + * INCLUDES + *********************/ +#include +#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_TASK_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 prio priority of the tmr (LV_TASK_PRIO_OFF means the tmr is stopped) + * @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; +} diff --git a/src/lv_misc/lv_tmr.h b/src/lv_misc/lv_tmr.h new file mode 100644 index 000000000..a5ba478ec --- /dev/null +++ b/src/lv_misc/lv_tmr.h @@ -0,0 +1,157 @@ +/** + * @file lv_tmr.h + */ + +#ifndef LV_TMR_H +#define LV_TMR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#include +#include +#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); + +/** + * 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