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