1 /***************************************************************************//**
2 * @file
3 * @brief SLEEPTIMER hardware abstraction layer definition.
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #ifndef SL_SLEEPTIMER_HAL_H
32 #define SL_SLEEPTIMER_HAL_H
33
34 #include <stdint.h>
35 #include <stddef.h>
36 #include <stdbool.h>
37 #include "em_device.h"
38 #include "sli_sleeptimer.h"
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 /*******************************************************************************
45 * Hardware Abstraction Layer of the sleep timer init.
46 ******************************************************************************/
47 void sleeptimer_hal_init_timer(void);
48
49 /*******************************************************************************
50 * Hardware Abstraction Layer to get the current timer count.
51 *
52 * @return Value in ticks of the timer counter.
53 ******************************************************************************/
54 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
55 uint32_t sleeptimer_hal_get_counter(void);
56
57 /*******************************************************************************
58 * Hardware Abstraction Layer to get a timer comparator value.
59 *
60 * @return Value in ticks of the timer comparator.
61 ******************************************************************************/
62 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
63 uint32_t sleeptimer_hal_get_compare(void);
64
65 /*******************************************************************************
66 * Hardware Abstraction Layer to set a timer comparator value.
67 *
68 * @param value Number of ticks to set.
69 ******************************************************************************/
70 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
71 void sleeptimer_hal_set_compare(uint32_t value);
72
73 /*******************************************************************************
74 * Hardware Abstraction Layer to set a comparator value to trigger a
75 * peripheral request signal to initialize.
76 *
77 * @param value Number of ticks to set.
78 ******************************************************************************/
79 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
80 void sleeptimer_hal_set_compare_prs_hfxo_startup(int32_t value);
81
82 /*******************************************************************************
83 * Hardware Abstraction Layer to get the timer frequency.
84 ******************************************************************************/
85 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
86 uint32_t sleeptimer_hal_get_timer_frequency(void);
87
88 /*******************************************************************************
89 * Hardware Abstraction Layer to enable timer interrupts.
90 *
91 * @param local_flag Internal interrupt flag.
92 ******************************************************************************/
93 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
94 void sleeptimer_hal_enable_int(uint8_t local_flag);
95
96 /*******************************************************************************
97 * Hardware Abstraction Layer to disable timer interrupts.
98 *
99 * @param local_flag Internal interrupt flag.
100 ******************************************************************************/
101 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
102 void sleeptimer_hal_disable_int(uint8_t local_flag);
103
104 /*******************************************************************************
105 * Hardware Abstraction Layer to set timer interrupts.
106 *
107 * @param local_flag Internal interrupt flag.
108 ******************************************************************************/
109 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
110 void sleeptimer_hal_set_int(uint8_t local_flag);
111
112 /*******************************************************************************
113 * Hardware Abstraction Layer to get the sleeptimer's clock accuracy.
114 *
115 * @return Clock accuracy in PPM.
116 ******************************************************************************/
117 uint16_t sleeptimer_hal_get_clock_accuracy(void);
118
119 /*******************************************************************************
120 * Hardware Abstraction Layer to get the capture channel value.
121 *
122 * @note Not supported by all peripherals Sleeptimer can use.
123 *
124 * @return Capture value.
125 ******************************************************************************/
126 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
127 uint32_t sleeptimer_hal_get_capture(void);
128
129 /*******************************************************************************
130 * Hardware Abstraction Layer to reset PRS signal triggered by the associated
131 * peripheral.
132 *
133 * @note Not supported by all peripherals Sleeptimer can use.
134 ******************************************************************************/
135 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
136 void sleeptimer_hal_reset_prs_signal(void);
137
138 /*******************************************************************************
139 * Hardware Abstraction Layer to disable PRS compare and capture channel.
140 *
141 * @note Not supported by all peripherals Sleeptimer can use.
142 ******************************************************************************/
143 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
144 void sleeptimer_hal_disable_prs_compare_and_capture_channel(void);
145
146 /*******************************************************************************
147 * Process the timer interrupt.
148 *
149 * @param flags Internal interrupt flag.
150 ******************************************************************************/
151 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
152 void process_timer_irq(uint8_t local_flag);
153
154 /***************************************************************************//**
155 * @brief
156 * Convert prescaler divider to a logarithmic value. It only works for even
157 * numbers equal to 2^n.
158 *
159 * @param[in] presc
160 * Prescaler value used to set the frequency divider. The divider is equal to
161 * ('presc' + 1). If a divider value is passed for 'presc', 'presc' will be
162 * equal to (divider - 1).
163 *
164 * @return
165 * Logarithm base 2 (binary) value, i.e. exponent as used by fixed
166 * 2^n prescalers.
167 ******************************************************************************/
sleeptimer_hal_presc_to_log2(uint32_t presc)168 __STATIC_INLINE uint32_t sleeptimer_hal_presc_to_log2(uint32_t presc)
169 {
170 uint32_t log2;
171
172 // Integer prescalers take argument less than 32768.
173 EFM_ASSERT(presc < 32768U);
174
175 // Count leading zeroes and "reverse" result. Consider divider value to get
176 // exponent n from 2^n, so ('presc' +1).
177 log2 = 31UL - __CLZ(presc + (uint32_t) 1);
178
179 // Check that prescaler is a 2^n number.
180 EFM_ASSERT(presc == (SL_Log2ToDiv(log2) - 1U));
181
182 return log2;
183 }
184
185 #ifdef __cplusplus
186 }
187 #endif
188
189 #endif /* SL_SLEEPTIMER_HAL_H */
190