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)95 static 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)109 static 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