aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/mps2/an519/native_drivers/timer_cmsdk/timer_cmsdk.h
blob: 52d9d5c986a54df07a416eae13ad1ddaa2c3f483 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
 * Copyright (c) 2016-2017 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * \file timer_cmsdk.h
 * \brief Generic driver for CMSDK APB Timers.
 *        The timer is a 32-bit down-counter with the following features:
 *        - optional programmable external clock source
 *        - programmable interrupt source, triggered if counter reaches 0
 *        - automatic reload if counter reaches 0
 */

#ifndef __CMSDK_TIMER_DRV_H__
#define __CMSDK_TIMER_DRV_H__

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/* Maximum reload value */
#define CMSDK_TIMER_MAX_RELOAD        INT32_MAX /* max of 32-bit */
#define CMSDK_TIMER_DEFAULT_RELOAD    CMSDK_TIMER_MAX_RELOAD

/** CMSDK timer device configuration structure */
struct cmsdk_timer_dev_cfg_t {
    const uintptr_t base;  /*!< Timer base address */
};

/** CMSDK timer device data structure */
struct cmsdk_timer_dev_data_t {
    bool is_initialized;  /*!< Indicates if the timer is initialized */
};

/* CMSDK timer device structure */
struct cmsdk_timer_dev_t {
    const struct cmsdk_timer_dev_cfg_t* const cfg;  /*!< Timer configuration */
    struct cmsdk_timer_dev_data_t* const data;      /*!< Timer data */
};

/**
 * \brief Initializes timer to a known default state, which is:
 *          - timer disabled
 *          - timer interrupt disabled
 *          - clock source set to internal
 *          - external input disabled
 *          - reload value maxed out
 *        Init should be called prior to any other process and
 *        it's the caller's responsibility to follow proper call order.
 *
 * \param[in] dev Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_init(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Checks if a timer is initialized.
 *
 * \param[in] dev Timer configuration \ref cmsdk_timer_dev_t
 *
 * \return true if initialized, false otherwise
 */
bool cmsdk_timer_is_initialized(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Enables external input, which could be used as clock source
 *        by calling \ref cmsdk_timer_set_clock_to_external.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_enable_external_input(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Disables external input.
 *        Make sure if the timer is explicitly wanted to be stopped or set
 *        the clock source to internal by \ref cmsdk_timer_set_clock_to_internal.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_disable_external_input(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Checks if external input is enabled.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 *
 * \return true if enabled, false otherwise
 */
bool cmsdk_timer_is_external_input_enabled(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Sets the clock source to internal.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_set_clock_to_internal(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Sets the clock source to external.
 *        Make sure external input is enabled correspondingly
 *        by \ref cmsdk_timer_enable_external_input.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_set_clock_to_external(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Checks if clock source is external input.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 *
 * \return true if external, false if internal
 */
bool cmsdk_timer_is_clock_external(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Enables timer operation.
 *
 * \param[in] dev Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_enable(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Disables the given hardware timer.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_disable(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Checks if a timer is enabled.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 *
 * \return true if enabled, false otherwise
 */
bool cmsdk_timer_is_enabled(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Enables timer interrupt.
 *
 * \param[in] dev       Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_enable_interrupt(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Disables timer interrupt.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_disable_interrupt(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Checks if a timer interrupt is enabled.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 *
 * \return true if enabled, false otherwise
 */
bool cmsdk_timer_is_interrupt_enabled(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Gets timer interrupt status
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 *
 * * \return true if active, false otherwise
 */
bool cmsdk_timer_is_interrupt_active(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Clears timer interrupt
 *        The interrupt request is held until it is cleared.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_clear_interrupt(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Reads timer current value.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 *
 * \return Timer value
 */
uint32_t cmsdk_timer_get_current_value(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Sets the reload value of the selected timer.
 *
 *        New reload value takes effect when:
 *        - timer is restarted
 *        - on timer underflow
 *        - when cmsdk_timer_reset is called
 *
 * \note  In r1p0 technical reference manual it's incorrectly stated
 *        writing the reload value automatically sets the current value also.
 *        r1p1 technical reference manual includes the fix.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 * \param[in] reload Timer reload value to set.
 *            This is the start value of the 32-bit down counter,
 *            which automatically reloaded if 0 is reached.
 */
void cmsdk_timer_set_reload_value(const struct cmsdk_timer_dev_t* dev,
                                  uint32_t reload);

/**
 * \brief Resets the timer counter to the reload value instantly
 *        (i.e. without waiting for underflow).
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 */
void cmsdk_timer_reset(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Gets the reload value of the selected timer.
 *        This is the start value of the 32-bit down counter,
 *        which is automatically reloaded if 0 is reached by the counter.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 *
 * \return Reload value of the selected timer.
 */
uint32_t cmsdk_timer_get_reload_value(const struct cmsdk_timer_dev_t* dev);

/**
 * \brief Reads the number of ticks elapsed in the current cycle.
 *
 * \param[in] dev  Timer configuration \ref cmsdk_timer_dev_t
 *
 * \return Get elapsed number of ticks since last reload was set.
 *         Elapsed = (Reload value - Current value)
 */
uint32_t cmsdk_timer_get_elapsed_value(const struct cmsdk_timer_dev_t* dev);

#ifdef __cplusplus
}
#endif
#endif /* __CMSDK_TIMER_DRV_H__ */