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