/* ---------------------------------------------------------------------------- * Copyright (c) 2020-2030 OnMicro Limited. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of OnMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * -------------------------------------------------------------------------- */ /** * @file om_time.h * @brief * @date 06. Aug 2020 * @author OnMicro SW Team * * @defgroup OM_TIME Time * @ingroup COMMON * @brief Time * @details Time * * @version * Version 1.0 * - Initial release * * @{ */ #ifndef __OM_TIME_H #define __OM_TIME_H #ifdef __cplusplus extern "C" { #endif /********************************************************************* * INCLUDES */ #include "om_driver.h" /********************************************************************* * MACROS */ /// Max timer tick #define OM_TIMER_MAX_TICK PMU_TIMER_MAX_TICK /// Max timer delay #define OM_TIMER_MAX_DELAY (OM_TIMER_MAX_TICK/2 - 1) /// Invalid time #define OM_TIME_INVALID 0xFFFFFFFFU /********************************************************************* * TYPEDEFS */ /********************************************************************* * EXTERN VARIABLES */ /********************************************************************* * EXTERN FUNCTIONS */ /** * @brief get current stack time(tick) * * @return current time, uint is 30.5us **/ __STATIC_FORCEINLINE uint32_t om_time(void) { return drv_pmu_timer_cnt_get(); } /** * @brief convert time to safe * * @param[in] time time * * @return safe time **/ __STATIC_FORCEINLINE uint32_t om_time_to_safe(uint32_t time) { #if (OM_TIMER_MAX_TICK == 0xFFFFFFFF) return time; #else return time & OM_TIMER_MAX_TICK; #endif } /** * @brief time increase + * * @param[in] time time * @param[in] increase +value * * @return increase result **/ __STATIC_FORCEINLINE uint32_t om_time_increase(uint32_t time, uint32_t increase) { #if (OM_TIMER_MAX_TICK == 0xFFFFFFFF) return time + increase; #else OM_ASSERT(time <= OM_TIMER_MAX_TICK); return om_time_to_safe(time + increase); #endif } /** * @brief time decrease - * * @param[in] time time value * @param[in] decrease -value * * @return decrease result **/ __STATIC_FORCEINLINE uint32_t om_time_decrease(uint32_t time, uint32_t decrease) { #if (OM_TIMER_MAX_TICK == 0xFFFFFFFF) return time - decrease; #else OM_ASSERT(time <= OM_TIMER_MAX_TICK); return (time < decrease) ? (OM_TIMER_MAX_TICK + 1 - (decrease - time)) : (time - decrease); #endif } /** * @brief different between with two time * * @param[in] me one time * @param[in] he another time * * @return different **/ __STATIC_FORCEINLINE uint32_t om_time_diff(uint32_t me, uint32_t he) { #if (OM_TIMER_MAX_TICK == 0xFFFFFFFF) uint32_t diff1 = me - he; uint32_t diff2 = he - me; #else uint32_t diff1 = (me > he) ? (me - he) : (he - me); uint32_t diff2 = OM_TIMER_MAX_TICK - diff1 + 1; #endif return OM_MIN(diff1, diff2); } /** * @brief compare between with two time * * @param[in] me one time * @param[in] he another time * * @return if me is smaller or equeal, return true, otherwise return false. **/ __STATIC_FORCEINLINE bool om_time_compare_equal_lesser(uint32_t me, uint32_t he) { #if (OM_TIMER_MAX_TICK == 0xFFFFFFFF) return (he - me < OM_TIMER_MAX_DELAY); #else return (me > he) ? (me - he > OM_TIMER_MAX_DELAY) : (he - me < OM_TIMER_MAX_DELAY); #endif } /** * @brief compare between with two time * * @param[in] me one time * @param[in] he another time * * @return if me is smaller, return true, otherwise return false. **/ __STATIC_FORCEINLINE bool om_time_compare_lesser(uint32_t me, uint32_t he) { return (me != he) && om_time_compare_equal_lesser(me, he); } /** * @brief compare between with two time * * @param[in] me one time * @param[in] he another time * * @return if me is greater or equeal, return true, otherwise return false. **/ __STATIC_FORCEINLINE bool om_time_compare_equal_greater(uint32_t me, uint32_t he) { return (me == he) || !om_time_compare_equal_lesser(me, he); } /** * @brief compare between with two time * * @param[in] me one time * @param[in] he another time * * @return if me is greater, return true, otherwise return false. **/ __STATIC_FORCEINLINE bool om_time_compare_greater(uint32_t me, uint32_t he) { return !om_time_compare_equal_lesser(me, he); } /** * @brief whether time is pasted * * @param[in] time time * @param[in] cur_time current time * * @return whether pasted **/ __STATIC_FORCEINLINE bool om_time_past(uint32_t time, uint32_t cur_time) { return om_time_compare_equal_lesser(time, cur_time); } /** * @brief time pasting time * * @param[in] time time * @param[in] cur_time current time * * @return 0:pasted, >0:will past time **/ __STATIC_FORCEINLINE uint32_t om_time_pasting_time(uint32_t time, uint32_t cur_time) { uint32_t delay; #if (OM_TIMER_MAX_TICK == 0xFFFFFFFF) delay = time - cur_time; #else if (time > cur_time) delay = time - cur_time; else delay = OM_TIMER_MAX_TICK - cur_time + time; #endif return (delay>OM_TIMER_MAX_DELAY) ? 0 : delay; } /** * @brief time delay tick is pasted * * @param[in] delay delay with tick * @param[in] prev_past_time prev delay time, if delay pasted, the value will be modify to current time * * @return pasted **/ __STATIC_FORCEINLINE bool om_time_delay_past(uint32_t delay, uint32_t *prev_past_time) { bool pasted; uint32_t cur_time = om_time(); if(*prev_past_time == OM_TIMER_MAX_TICK) *prev_past_time = cur_time; pasted = om_time_diff(cur_time, *prev_past_time) > delay; if(pasted) *prev_past_time = cur_time; return pasted; } /** * @brief time intersection * * @param[in] time1 time1 * @param[in] time1_duration time1_duration * @param[in] time2 time2 * @param[in] time2_duration time2_duration * * @return whether is intersection **/ __STATIC_FORCEINLINE bool om_time_intersection(uint32_t time1, uint32_t time1_duration, uint32_t time2, uint32_t time2_duration) { uint32_t time1_tail = om_time_increase(time1, time1_duration); uint32_t time2_tail = om_time_increase(time2, time2_duration); return !(om_time_compare_equal_lesser(time2_tail, time1) || om_time_compare_equal_lesser(time1_tail, time2)); } #ifdef __cplusplus } #endif #endif /** @} */