1 /* 2 * Copyright (c) 2020 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL 8 #define HAL_TICKER_FSEC_PER_USEC 1000000000UL 9 #define HAL_TICKER_PSEC_PER_USEC 1000000UL 10 #define HAL_TICKER_FSEC_PER_PSEC 1000UL 11 12 /* Macro defining the minimum counter compare offset */ 13 #define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3 14 15 /* Macro defining the max. counter update latency in ticks */ 16 #define HAL_TICKER_CNTR_SET_LATENCY 0 17 18 /* Macro defines the h/w supported most significant bit */ 19 #define HAL_TICKER_CNTR_MSBIT 23 20 21 /* Macro defining the HW supported counter bits */ 22 #define HAL_TICKER_CNTR_MASK 0x00FFFFFF 23 24 /* Macro to translate microseconds to tick units. 25 * NOTE: This returns the floor value. 26 */ 27 #define HAL_TICKER_US_TO_TICKS(x) \ 28 ( \ 29 ((uint32_t)(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) / \ 30 HAL_TICKER_CNTR_CLK_UNIT_FSEC)) & \ 31 HAL_TICKER_CNTR_MASK \ 32 ) 33 34 /* Macro to translate microseconds to tick units. 35 * NOTE: This returns the ceil value. 36 */ 37 #define HAL_TICKER_US_TO_TICKS_CEIL(x) \ 38 ( \ 39 DIV_ROUND_UP(((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC), \ 40 HAL_TICKER_CNTR_CLK_UNIT_FSEC) & \ 41 HAL_TICKER_CNTR_MASK \ 42 ) 43 44 /* Macro to translate tick units to microseconds. */ 45 #define HAL_TICKER_TICKS_TO_US(x) \ 46 ( \ 47 ((uint32_t)(((uint64_t)(x) * HAL_TICKER_CNTR_CLK_UNIT_FSEC) / \ 48 HAL_TICKER_FSEC_PER_USEC)) \ 49 ) 50 51 /* Macro returning remainder in picoseconds (to fit in 32-bits) */ 52 #define HAL_TICKER_REMAINDER(x) \ 53 ( \ 54 ( \ 55 ((uint64_t) (x) * HAL_TICKER_FSEC_PER_USEC) \ 56 - ((uint64_t)HAL_TICKER_US_TO_TICKS(x) * \ 57 HAL_TICKER_CNTR_CLK_UNIT_FSEC) \ 58 ) \ 59 / HAL_TICKER_FSEC_PER_PSEC \ 60 ) 61 62 /* Macro defining the remainder resolution/range 63 * ~ 1000000 * HAL_TICKER_TICKS_TO_US(1) 64 */ 65 #define HAL_TICKER_REMAINDER_RANGE \ 66 HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC) 67 68 /* Macro defining the margin for positioning re-scheduled nodes */ 69 #define HAL_TICKER_RESCHEDULE_MARGIN \ 70 HAL_TICKER_US_TO_TICKS(150) 71 72 /* Remove ticks and return positive remainder value in microseconds */ hal_ticker_remove_jitter(uint32_t * ticks,uint32_t * remainder)73static inline void hal_ticker_remove_jitter(uint32_t *ticks, 74 uint32_t *remainder) 75 { 76 /* Is remainder less than 1 us */ 77 if ((*remainder & BIT(31)) || !(*remainder / HAL_TICKER_PSEC_PER_USEC)) { 78 *ticks -= 1U; 79 *remainder += HAL_TICKER_CNTR_CLK_UNIT_FSEC / HAL_TICKER_FSEC_PER_PSEC; 80 } 81 82 /* pico seconds to micro seconds unit */ 83 *remainder /= HAL_TICKER_PSEC_PER_USEC; 84 } 85 86 /* Add ticks and return positive remainder value in microseconds */ hal_ticker_add_jitter(uint32_t * ticks,uint32_t * remainder)87static inline void hal_ticker_add_jitter(uint32_t *ticks, uint32_t *remainder) 88 { 89 /* Is remainder less than 1 us */ 90 if ((*remainder & BIT(31)) || !(*remainder / HAL_TICKER_PSEC_PER_USEC)) { 91 *ticks += 1U; 92 *remainder += HAL_TICKER_CNTR_CLK_UNIT_FSEC / HAL_TICKER_FSEC_PER_PSEC; 93 } 94 95 /* pico seconds to micro seconds unit */ 96 *remainder /= HAL_TICKER_PSEC_PER_USEC; 97 } 98