1 /*
2  * Copyright (c) 2016-2019 Arm Limited. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __TIMER_CMSDK_DRV_H__
18 #define __TIMER_CMSDK_DRV_H__
19 
20 #include <stdint.h>
21 #include <stdbool.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /* Maximum reload value */
28 #define TIMER_CMSDK_MAX_RELOAD        UINT32_MAX /* max of 32-bit */
29 #define TIMER_CMSDK_DEFAULT_RELOAD    TIMER_CMSDK_MAX_RELOAD
30 
31 /** CMSDK timer device configuration structure */
32 struct timer_cmsdk_dev_cfg_t {
33     const uintptr_t base;  /*!< Timer base address */
34 };
35 
36 /** CMSDK timer device data structure */
37 struct timer_cmsdk_dev_data_t {
38     bool is_initialized;  /*!< Indicates if the timer is initialized */
39 };
40 
41 /* CMSDK timer device structure */
42 struct timer_cmsdk_dev_t {
43     const struct timer_cmsdk_dev_cfg_t* const cfg;  /*!< Timer configuration */
44     struct timer_cmsdk_dev_data_t* const data;      /*!< Timer data */
45 };
46 
47 /**
48  * \brief Initializes timer to a known default state, which is:
49  *          - timer disabled
50  *          - timer interrupt disabled
51  *          - clock source set to internal
52  *          - external input disabled
53  *          - reload value maxed out
54  *        Init should be called prior to any other process and
55  *        it's the caller's responsibility to follow proper call order.
56  *
57  * \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
58  */
59 void timer_cmsdk_init(const struct timer_cmsdk_dev_t* dev);
60 
61 /**
62  * \brief Checks if a timer is initialized.
63  *
64  * \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
65  *
66  * \return true if initialized, false otherwise
67  */
68 bool timer_cmsdk_is_initialized(const struct timer_cmsdk_dev_t* dev);
69 
70 /**
71  * \brief Enables external input, which could be used as clock source
72  *        by calling \ref timer_cmsdk_set_clock_to_external.
73  *
74  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
75  */
76 void timer_cmsdk_enable_external_input(const struct timer_cmsdk_dev_t* dev);
77 
78 /**
79  * \brief Disables external input.
80  *        Make sure if the timer is explicitly wanted to be stopped or set
81  *        the clock source to internal by \ref timer_cmsdk_set_clock_to_internal.
82  *
83  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
84  */
85 void timer_cmsdk_disable_external_input(const struct timer_cmsdk_dev_t* dev);
86 
87 /**
88  * \brief Checks if external input is enabled.
89  *
90  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
91  *
92  * \return true if enabled, false otherwise
93  */
94 bool timer_cmsdk_is_external_input_enabled(const struct timer_cmsdk_dev_t* dev);
95 
96 /**
97  * \brief Sets the clock source to internal.
98  *
99  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
100  */
101 void timer_cmsdk_set_clock_to_internal(const struct timer_cmsdk_dev_t* dev);
102 
103 /**
104  * \brief Sets the clock source to external.
105  *        Make sure external input is enabled correspondingly
106  *        by \ref timer_cmsdk_enable_external_input.
107  *
108  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
109  */
110 void timer_cmsdk_set_clock_to_external(const struct timer_cmsdk_dev_t* dev);
111 
112 /**
113  * \brief Checks if clock source is external input.
114  *
115  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
116  *
117  * \return true if external, false if internal
118  */
119 bool timer_cmsdk_is_clock_external(const struct timer_cmsdk_dev_t* dev);
120 
121 /**
122  * \brief Enables timer operation.
123  *
124  * \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
125  */
126 void timer_cmsdk_enable(const struct timer_cmsdk_dev_t* dev);
127 
128 /**
129  * \brief Disables the given hardware timer.
130  *
131  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
132  */
133 void timer_cmsdk_disable(const struct timer_cmsdk_dev_t* dev);
134 
135 /**
136  * \brief Checks if a timer is enabled.
137  *
138  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
139  *
140  * \return true if enabled, false otherwise
141  */
142 bool timer_cmsdk_is_enabled(const struct timer_cmsdk_dev_t* dev);
143 
144 /**
145  * \brief Enables timer interrupt.
146  *
147  * \param[in] dev       Timer configuration \ref timer_cmsdk_dev_t
148  */
149 void timer_cmsdk_enable_interrupt(const struct timer_cmsdk_dev_t* dev);
150 
151 /**
152  * \brief Disables timer interrupt.
153  *
154  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
155  */
156 void timer_cmsdk_disable_interrupt(const struct timer_cmsdk_dev_t* dev);
157 
158 /**
159  * \brief Checks if a timer interrupt is enabled.
160  *
161  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
162  *
163  * \return true if enabled, false otherwise
164  */
165 bool timer_cmsdk_is_interrupt_enabled(const struct timer_cmsdk_dev_t* dev);
166 
167 /**
168  * \brief Gets timer interrupt status
169  *
170  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
171  *
172  * * \return true if active, false otherwise
173  */
174 bool timer_cmsdk_is_interrupt_active(const struct timer_cmsdk_dev_t* dev);
175 
176 /**
177  * \brief Clears timer interrupt
178  *        The interrupt request is held until it is cleared.
179  *
180  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
181  */
182 void timer_cmsdk_clear_interrupt(const struct timer_cmsdk_dev_t* dev);
183 
184 /**
185  * \brief Reads timer current value.
186  *
187  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
188  *
189  * \return Timer value
190  */
191 uint32_t timer_cmsdk_get_current_value(const struct timer_cmsdk_dev_t* dev);
192 
193 /**
194  * \brief Sets the reload value of the selected timer.
195  *
196  *        New reload value takes effect when:
197  *        - timer is restarted
198  *        - on timer underflow
199  *        - when timer_cmsdk_reset is called
200  *
201  * \note  In r1p0 technical reference manual it's incorrectly stated
202  *        writing the reload value automatically sets the current value also.
203  *        r1p1 technical reference manual includes the fix.
204  *
205  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
206  * \param[in] reload Timer reload value to set.
207  *            This is the start value of the 32-bit down counter,
208  *            which automatically reloaded if 0 is reached.
209  */
210 void timer_cmsdk_set_reload_value(const struct timer_cmsdk_dev_t* dev,
211                                   uint32_t reload);
212 
213 /**
214  * \brief Resets the timer counter to the reload value instantly
215  *        (i.e. without waiting for underflow).
216  *
217  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
218  */
219 void timer_cmsdk_reset(const struct timer_cmsdk_dev_t* dev);
220 
221 /**
222  * \brief Gets the reload value of the selected timer.
223  *        This is the start value of the 32-bit down counter,
224  *        which is automatically reloaded if 0 is reached by the counter.
225  *
226  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
227  *
228  * \return Reload value of the selected timer.
229  */
230 uint32_t timer_cmsdk_get_reload_value(const struct timer_cmsdk_dev_t* dev);
231 
232 /**
233  * \brief Reads the number of ticks elapsed in the current cycle.
234  *
235  * \param[in] dev  Timer configuration \ref timer_cmsdk_dev_t
236  *
237  * \return Get elapsed number of ticks since last reload was set.
238  *         Elapsed = (Reload value - Current value)
239  */
240 uint32_t timer_cmsdk_get_elapsed_value(const struct timer_cmsdk_dev_t* dev);
241 
242 #ifdef __cplusplus
243 }
244 #endif
245 #endif /* __TIMER_CMSDK_DRV_H__ */
246