cyhal_timer.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /***************************************************************************//**
  2. * \file cyhal_timer.h
  3. *
  4. * \brief
  5. * Provides a high level interface for interacting with the Infineon Timer/Counter.
  6. * This interface abstracts out the chip specific details. If any chip specific
  7. * functionality is necessary, or performance is critical the low level functions
  8. * can be used directly.
  9. *
  10. ********************************************************************************
  11. * \copyright
  12. * Copyright 2018-2021 Cypress Semiconductor Corporation (an Infineon company) or
  13. * an affiliate of Cypress Semiconductor Corporation
  14. *
  15. * SPDX-License-Identifier: Apache-2.0
  16. *
  17. * Licensed under the Apache License, Version 2.0 (the "License");
  18. * you may not use this file except in compliance with the License.
  19. * You may obtain a copy of the License at
  20. *
  21. * http://www.apache.org/licenses/LICENSE-2.0
  22. *
  23. * Unless required by applicable law or agreed to in writing, software
  24. * distributed under the License is distributed on an "AS IS" BASIS,
  25. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  26. * See the License for the specific language governing permissions and
  27. * limitations under the License.
  28. *******************************************************************************/
  29. /**
  30. * \addtogroup group_hal_timer Timer (Timer/Counter)
  31. * \ingroup group_hal
  32. * \{
  33. * High level interface for interacting with the Timer/Counter hardware resource.
  34. *
  35. * The timer block is commonly used to measure the time of occurrence of an event,
  36. * to measure the time difference between two events or perform an action after
  37. * a specified period of time. The driver also allows the user to invoke a callback function
  38. * when a particular event occurs.
  39. *
  40. * Some use case scenarios of timer -
  41. *
  42. * * Creating a periodic interrupt for executing periodic tasks
  43. * * Measuring time between two events
  44. * * Triggering other system resources after a certain number of events
  45. * * Capturing time stamps when events occur
  46. *
  47. * \section subsection_timer_features Features
  48. * * Runtime configurable parameters like period and compare value - \ref cyhal_timer_cfg_t
  49. * * Configurable counting direction - \ref cyhal_timer_direction_t
  50. * * Interrupt on various events - \ref cyhal_timer_event_t
  51. * * Continuous or One Shot run modes
  52. *
  53. * \section subsection_timer_quickstart Quick Start
  54. *
  55. * \ref cyhal_timer_init can be used for timer initialization by providing the timer object - \ref cyhal_timer_t,
  56. * and shared clock source - <b> clk </b> (optional). The timer parameters needs to be populated in \ref cyhal_timer_cfg_t structure.
  57. * The timer then needs to be configured by using the \ref cyhal_timer_configure function.
  58. *
  59. * \note A default frequency is set when an existing clock divider - <b> clk </b> is not provided to \ref cyhal_timer_init which is
  60. * defined by the macro - \ref CYHAL_TIMER_DEFAULT_FREQ.
  61. *
  62. * \warning Currently there is no support for pin connections to Timer using this driver. So, the <b> pin </b> should be
  63. * assigned as \ref NC while using the \ref cyhal_timer_init to initialize the timer.
  64. *
  65. *
  66. * See \ref subsection_timer_snippet_1.
  67. *
  68. * \section subsection_timer_sample_snippets Code Snippets
  69. *
  70. * \subsection subsection_timer_snippet_1 Snippet 1: Measuring time of an operation
  71. * The following snippet initializes a Timer and measures the time between two events.
  72. * The <b>clk</b> need not be provided, in which case a clock resource is assigned.
  73. * \snippet hal_timer.c snippet_cyhal_timer_event_measure
  74. *
  75. * \subsection subsection_timer_snippet_2 Snippet 2: Handling an event in a callback function
  76. * The following snippet initializes a Timer and triggers an event after every one second.
  77. * The <b>clk</b> need not be provided (NULL), in which case a clock resource is assigned.
  78. * \snippet hal_timer.c snippet_cyhal_timer_event_interrupt
  79. *
  80. */
  81. #pragma once
  82. #include <stdint.h>
  83. #include <stdbool.h>
  84. #include "cy_result.h"
  85. #include "cyhal_hw_types.h"
  86. #if defined(__cplusplus)
  87. extern "C" {
  88. #endif
  89. /** \addtogroup group_hal_results_timer Timer HAL Results
  90. * Timer specific return codes
  91. * \ingroup group_hal_results
  92. * \{ *//**
  93. */
  94. /** Bad argument. eg: null pointer */
  95. #define CYHAL_TIMER_RSLT_ERR_BAD_ARGUMENT \
  96. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 0))
  97. /** Failed to initialize Timer clock */
  98. #define CYHAL_TIMER_RSLT_ERR_CLOCK_INIT \
  99. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 1))
  100. /** Failed to initialize Timer */
  101. #define CYHAL_TIMER_RSLT_ERR_INIT \
  102. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 2))
  103. /** Cannot change the timer frequency when a shared clock divider is in use */
  104. #define CYHAL_TIMER_RSLT_ERR_SHARED_CLOCK \
  105. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 3))
  106. /**
  107. * \}
  108. */
  109. /*******************************************************************************
  110. * Enumerations
  111. *******************************************************************************/
  112. /** Timer directions */
  113. typedef enum
  114. {
  115. CYHAL_TIMER_DIR_UP, //!< Counts up
  116. CYHAL_TIMER_DIR_DOWN, //!< Counts down
  117. CYHAL_TIMER_DIR_UP_DOWN, //!< Counts up and down, terminal count occurs on both overflow and underflow.
  118. } cyhal_timer_direction_t;
  119. /** Timer/counter interrupt triggers */
  120. typedef enum {
  121. CYHAL_TIMER_IRQ_NONE = 0, /**< No interrupt handled **/
  122. CYHAL_TIMER_IRQ_TERMINAL_COUNT = 1 << 0, /**< Interrupt when terminal count is reached **/
  123. CYHAL_TIMER_IRQ_CAPTURE_COMPARE = 1 << 1, /**< Interrupt when Compare/Capture value is reached **/
  124. CYHAL_TIMER_IRQ_ALL = (1 << 2) - 1, /**< Interrupt on terminal count and Compare/Capture values **/
  125. } cyhal_timer_event_t;
  126. /** Timer/counter input signal */
  127. typedef enum
  128. {
  129. CYHAL_TIMER_INPUT_START, //!< Start signal
  130. CYHAL_TIMER_INPUT_STOP, //!< Stop signal
  131. CYHAL_TIMER_INPUT_RELOAD, //!< Reload signal
  132. CYHAL_TIMER_INPUT_COUNT, //!< Count signal
  133. CYHAL_TIMER_INPUT_CAPTURE, //!< Capture signal
  134. } cyhal_timer_input_t;
  135. /** Timer/counter output signal */
  136. typedef enum
  137. {
  138. CYHAL_TIMER_OUTPUT_OVERFLOW, //!< Overflow signal
  139. CYHAL_TIMER_OUTPUT_UNDERFLOW, //!< Underflow signal
  140. CYHAL_TIMER_OUTPUT_COMPARE_MATCH, //!< Compare Match signal
  141. CYHAL_TIMER_OUTPUT_TERMINAL_COUNT, //!< Terminal count signal (logical OR of overflow and underflow signal)
  142. } cyhal_timer_output_t;
  143. /*******************************************************************************
  144. * Data Structures
  145. *******************************************************************************/
  146. /** @brief Describes the current configuration of a timer/counter */
  147. typedef struct
  148. {
  149. /**
  150. * Whether the timer is set to continuously run.
  151. * If true, the timer will run forever.
  152. * Otherwise, the timer will run once and stop (one shot).
  153. */
  154. bool is_continuous; //!< Whether the timer/counter operates continuous (true) or one shot (false)
  155. cyhal_timer_direction_t direction; //!< Direction the timer/counter is running
  156. bool is_compare; //!< Is it in compare (true) or capture (false) mode
  157. uint32_t period; //!< Timer/counter period
  158. uint32_t compare_value; //!< Timer/counter comparison value
  159. uint32_t value; //!< Default value of the timer/counter. \ref cyhal_timer_reset() will also change counter to this value when called.
  160. } cyhal_timer_cfg_t;
  161. /*******************************************************************************
  162. * Typedefs
  163. *******************************************************************************/
  164. /** Handler for timer events */
  165. typedef void(*cyhal_timer_event_callback_t)(void *callback_arg, cyhal_timer_event_t event);
  166. /*******************************************************************************
  167. * Defines
  168. *******************************************************************************/
  169. /** Default timer frequency, used when an existing clock divider is not provided to \ref cyhal_timer_init() */
  170. #define CYHAL_TIMER_DEFAULT_FREQ (1000000u)
  171. /*******************************************************************************
  172. * Functions
  173. *******************************************************************************/
  174. /** Initialize the timer/counter peripheral and configure the pin. <br>
  175. * See \ref subsection_timer_snippet_1.
  176. *
  177. * @param[out] obj Pointer to a timer/counter object. The caller must allocate the memory
  178. * for this object but the init function will initialize its contents.
  179. * @param[in] pin optional - The timer/counter compare/capture pin to initialize
  180. * @param[in] clk optional - The shared clock to use, if not provided a new clock will be allocated
  181. * and the timer frequency will be set to \ref CYHAL_TIMER_DEFAULT_FREQ
  182. * @return The status of the init request
  183. */
  184. cy_rslt_t cyhal_timer_init(cyhal_timer_t *obj, cyhal_gpio_t pin, const cyhal_clock_t *clk);
  185. /** Initialize the Timer peripheral using a configurator generated configuration struct
  186. *
  187. * @param[out] obj Pointer to a Timer object. The caller must allocate the memory
  188. * for this object but the init function will initialize its contents.
  189. * @param[in] cfg Configuration structure generated by a configurator.
  190. * @return The status of the init request
  191. */
  192. cy_rslt_t cyhal_timer_init_cfg(cyhal_timer_t *obj, const cyhal_timer_configurator_t *cfg);
  193. /** Deinitialize the timer/counter object
  194. *
  195. * @param[in,out] obj The timer/counter object
  196. */
  197. void cyhal_timer_free(cyhal_timer_t *obj);
  198. /** Updates the configuration and counter value of the timer/counter object. <br>
  199. * This function may temporary stop the timer if it is currently running.
  200. * See \ref subsection_timer_snippet_1.
  201. * @param[in] obj The timer/counter object
  202. * @param[in] cfg The configuration of the timer/counter
  203. * @return The status of the configure request
  204. */
  205. cy_rslt_t cyhal_timer_configure(cyhal_timer_t *obj, const cyhal_timer_cfg_t *cfg);
  206. /** Configures the timer frequency.
  207. * \note This is only valid to call if a null clock divider was provided to \ref cyhal_timer_init.
  208. * If a custom clock was provided its frequency should be adjusted directly.
  209. *
  210. * See \ref subsection_timer_snippet_1.
  211. * @param[in] obj The timer/counter object
  212. * @param[in] hz The frequency rate in Hz
  213. * @return The status of the set_frequency request
  214. */
  215. cy_rslt_t cyhal_timer_set_frequency(cyhal_timer_t *obj, uint32_t hz);
  216. /** Starts the timer/counter with the pre-set configuration from \ref cyhal_timer_configure.
  217. * This does not reset the counter. The count value will start from the value that was
  218. * set by the last operation to modify it. See \ref cyhal_timer_configure, and \ref
  219. * cyhal_timer_reset for how the value can be changed. If none of these functions have
  220. * been called, it will start from 0.<br>
  221. * See \ref subsection_timer_snippet_1.
  222. *
  223. * @param[in] obj The timer/counter object
  224. * @return The status of the start request
  225. */
  226. cy_rslt_t cyhal_timer_start(cyhal_timer_t *obj);
  227. /** Stops the timer/counter. Does not reset counter value. <br>
  228. *
  229. * @param[in] obj The timer/counter object
  230. * @return The status of the stop request
  231. */
  232. cy_rslt_t cyhal_timer_stop(cyhal_timer_t *obj);
  233. /** Reset the timer/counter value to the default value set from \ref cyhal_timer_configure.
  234. * If \ref cyhal_timer_configure was never called, this will reset timer/counter value to 0.
  235. * This function may temporary stop the timer. <br>
  236. *
  237. * @param[in] obj The timer/counter object
  238. * @return The status of the reset request
  239. */
  240. cy_rslt_t cyhal_timer_reset(cyhal_timer_t *obj);
  241. /** Reads the current value from the timer/counter <br>
  242. * See \ref subsection_timer_snippet_1.
  243. *
  244. * @param[in] obj The timer/counter object
  245. * @return The current value of the timer/counter
  246. */
  247. uint32_t cyhal_timer_read(const cyhal_timer_t *obj);
  248. /** Register a timer/counter callback handler<br>
  249. *
  250. * This function will be called when one of the events enabled by \ref cyhal_timer_enable_event occurs.
  251. *
  252. * See \ref subsection_timer_snippet_2.
  253. *
  254. * @param[in] obj The timer/counter object
  255. * @param[in] callback The callback handler which will be invoked when the event occurs
  256. * @param[in] callback_arg Generic argument that will be provided to the callback when called
  257. */
  258. void cyhal_timer_register_callback(cyhal_timer_t *obj, cyhal_timer_event_callback_t callback, void *callback_arg);
  259. /** Configure timer/counter event enablement <br>
  260. *
  261. * When an enabled event occurs, the function specified by \ref cyhal_timer_register_callback will be called.
  262. *
  263. * See \ref subsection_timer_snippet_2.
  264. *
  265. * @param[in] obj The timer/counter object
  266. * @param[in] event The timer/counter event type
  267. * @param[in] intr_priority The priority for NVIC interrupt events
  268. * @param[in] enable True to turn on interrupts, False to turn off
  269. */
  270. void cyhal_timer_enable_event(cyhal_timer_t *obj, cyhal_timer_event_t event, uint8_t intr_priority, bool enable);
  271. /** Connects a source signal and configures and enables a timer event to be
  272. * triggered from that signal. These timer events can be configured
  273. * independently and connect to the same or different source signals.
  274. * @note For "edge" signals, this function will default to rising edge. To control the edge type,
  275. * use @ref cyhal_timer_connect_digital2
  276. *
  277. * @param[in] obj Timer obj
  278. * @param[in] source Source signal obtained from another driver's cyhal_<PERIPH>_enable_output
  279. * @param[in] signal The timer input signal
  280. * @return The current status of the connection
  281. * */
  282. cy_rslt_t cyhal_timer_connect_digital(cyhal_timer_t *obj, cyhal_source_t source, cyhal_timer_input_t signal);
  283. /** Connects a source signal and configures and enables a timer event to be
  284. * triggered from that signal with a configurable edge type. These timer events
  285. * can be configured independently and connect to the same or different source signals.
  286. *
  287. * @param[in] obj Timer obj
  288. * @param[in] source Source signal obtained from another driver's cyhal_<PERIPH>_enable_output
  289. * @param[in] signal The timer input signal
  290. * @param[in] edge_type The edge type that should trigger the event. This must be consistent with the
  291. * edge type of `source`. If `source` produces a "level" signal, the only valid
  292. * value is @ref CYHAL_EDGE_TYPE_LEVEL. If `source` produces an "edge" signal, then
  293. * @ref CYHAL_EDGE_TYPE_LEVEL is not a valid value.
  294. * @return The current status of the connection
  295. * */
  296. cy_rslt_t cyhal_timer_connect_digital2(cyhal_timer_t *obj, cyhal_source_t source, cyhal_timer_input_t signal, cyhal_edge_type_t edge_type);
  297. /** Enables the specified output signal from a tcpwm that will be triggered
  298. * when the corresponding event occurs. Multiple output signals can be
  299. * configured simultaneously.
  300. *
  301. * @param[in] obj Timer obj
  302. * @param[in] signal The timer output signal
  303. * @param[out] source Pointer to user-allocated source signal object which
  304. * will be initialized by enable_output. \p source should be passed to
  305. * (dis)connect_digital functions to (dis)connect the associated endpoints.
  306. * @return The current status of the output enable
  307. * */
  308. cy_rslt_t cyhal_timer_enable_output(cyhal_timer_t *obj, cyhal_timer_output_t signal, cyhal_source_t *source);
  309. /** Disconnects a source signal and disables the timer event.
  310. *
  311. * @param[in] obj Timer obj
  312. * @param[in] source Source signal from cyhal_<PERIPH>_enable_output to disable
  313. * @param[in] signal The timer input signal
  314. * @return The status of the disconnection
  315. * */
  316. cy_rslt_t cyhal_timer_disconnect_digital(cyhal_timer_t *obj, cyhal_source_t source, cyhal_timer_input_t signal);
  317. /** Disables the specified output signal from a timer.
  318. *
  319. * @param[in] obj Timer obj
  320. * @param[in] signal The timer output signal
  321. * @return The status of the output disable
  322. * */
  323. cy_rslt_t cyhal_timer_disable_output(cyhal_timer_t *obj, cyhal_timer_output_t signal);
  324. #if defined(__cplusplus)
  325. }
  326. #endif
  327. #ifdef CYHAL_TIMER_IMPL_HEADER
  328. #include CYHAL_TIMER_IMPL_HEADER
  329. #endif /* CYHAL_TIMER_IMPL_HEADER */
  330. /** \} group_hal_timer */