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