cyhal_timer.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  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-2022 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(COMPONENT_CAT5)
  87. #include "cyhal_t2timer.h"
  88. #endif
  89. #if defined(__cplusplus)
  90. extern "C" {
  91. #endif
  92. /** \addtogroup group_hal_results_timer Timer HAL Results
  93. * Timer specific return codes
  94. * \ingroup group_hal_results
  95. * \{ *//**
  96. */
  97. /** Bad argument. eg: null pointer */
  98. #define CYHAL_TIMER_RSLT_ERR_BAD_ARGUMENT \
  99. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 0))
  100. /** Failed to initialize Timer clock */
  101. #define CYHAL_TIMER_RSLT_ERR_CLOCK_INIT \
  102. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 1))
  103. /** Failed to initialize Timer */
  104. #define CYHAL_TIMER_RSLT_ERR_INIT \
  105. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 2))
  106. /** Cannot change the timer frequency when a shared clock divider is in use */
  107. #define CYHAL_TIMER_RSLT_ERR_SHARED_CLOCK \
  108. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 3))
  109. /** Feature unsupported with this Timer */
  110. #define CYHAL_TIMER_RSLT_ERR_UNSUPPORTED \
  111. (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_TIMER, 4))
  112. /**
  113. * \}
  114. */
  115. /*******************************************************************************
  116. * Enumerations
  117. *******************************************************************************/
  118. /** Timer directions */
  119. typedef enum
  120. {
  121. CYHAL_TIMER_DIR_UP, //!< Counts up
  122. CYHAL_TIMER_DIR_DOWN, //!< Counts down
  123. CYHAL_TIMER_DIR_UP_DOWN, //!< Counts up and down, terminal count occurs on both overflow and underflow.
  124. } cyhal_timer_direction_t;
  125. /** Timer/counter interrupt triggers */
  126. typedef enum {
  127. CYHAL_TIMER_IRQ_NONE = 0, /**< No interrupt handled **/
  128. CYHAL_TIMER_IRQ_TERMINAL_COUNT = 1 << 0, /**< Interrupt when terminal count is reached **/
  129. CYHAL_TIMER_IRQ_CAPTURE_COMPARE = 1 << 1, /**< Interrupt when Compare/Capture value is reached **/
  130. CYHAL_TIMER_IRQ_ALL = (1 << 2) - 1, /**< Interrupt on terminal count and Compare/Capture values **/
  131. } cyhal_timer_event_t;
  132. /** Timer/counter input signal */
  133. typedef enum
  134. {
  135. CYHAL_TIMER_INPUT_START, //!< Start signal
  136. CYHAL_TIMER_INPUT_STOP, //!< Stop signal
  137. CYHAL_TIMER_INPUT_RELOAD, //!< Reload signal
  138. CYHAL_TIMER_INPUT_COUNT, //!< Count signal
  139. CYHAL_TIMER_INPUT_CAPTURE, //!< Capture signal
  140. } cyhal_timer_input_t;
  141. /** Timer/counter output signal */
  142. typedef enum
  143. {
  144. CYHAL_TIMER_OUTPUT_OVERFLOW, //!< Overflow signal
  145. CYHAL_TIMER_OUTPUT_UNDERFLOW, //!< Underflow signal
  146. CYHAL_TIMER_OUTPUT_COMPARE_MATCH, //!< Compare Match signal
  147. CYHAL_TIMER_OUTPUT_TERMINAL_COUNT, //!< Terminal count signal (logical OR of overflow and underflow signal)
  148. } cyhal_timer_output_t;
  149. /*******************************************************************************
  150. * Data Structures
  151. *******************************************************************************/
  152. /** @brief Describes the current configuration of a timer/counter */
  153. typedef struct
  154. {
  155. /**
  156. * Whether the timer is set to continuously run.
  157. * If true, the timer will run forever.
  158. * Otherwise, the timer will run once and stop (one shot).
  159. */
  160. bool is_continuous; //!< Whether the timer/counter operates continuous (true) or one shot (false)
  161. cyhal_timer_direction_t direction; //!< Direction the timer/counter is running
  162. bool is_compare; //!< Is it in compare (true) or capture (false) mode
  163. uint32_t period; //!< Timer/counter period
  164. uint32_t compare_value; //!< Timer/counter comparison value
  165. uint32_t value; //!< Default value of the timer/counter. \ref cyhal_timer_reset() will also change counter to this value when called.
  166. } cyhal_timer_cfg_t;
  167. /*******************************************************************************
  168. * Typedefs
  169. *******************************************************************************/
  170. /** Handler for timer events */
  171. typedef void(*cyhal_timer_event_callback_t)(void *callback_arg, cyhal_timer_event_t event);
  172. /*******************************************************************************
  173. * Defines
  174. *******************************************************************************/
  175. /** Default timer frequency, used when an existing clock divider is not provided to \ref cyhal_timer_init() */
  176. #define CYHAL_TIMER_DEFAULT_FREQ (1000000u)
  177. /*******************************************************************************
  178. * Functions
  179. *******************************************************************************/
  180. /** Initialize the timer/counter peripheral and configure the pin. <br>
  181. * See \ref subsection_timer_snippet_1.
  182. *
  183. * @param[out] obj Pointer to a timer/counter object. The caller must allocate the memory
  184. * for this object but the init function will initialize its contents.
  185. * @param[in] pin optional - The timer/counter compare/capture pin to initialize
  186. * @param[in] clk optional - The shared clock to use, if not provided a new clock will be allocated
  187. * and the timer frequency will be set to \ref CYHAL_TIMER_DEFAULT_FREQ
  188. * @return The status of the init request
  189. */
  190. cy_rslt_t cyhal_timer_init(cyhal_timer_t *obj, cyhal_gpio_t pin, const cyhal_clock_t *clk);
  191. /** Initialize the Timer peripheral using a configurator generated configuration struct
  192. *
  193. * @param[out] obj Pointer to a Timer object. The caller must allocate the memory
  194. * for this object but the init function will initialize its contents.
  195. * @param[in] cfg Configuration structure generated by a configurator.
  196. * @return The status of the init request
  197. */
  198. cy_rslt_t cyhal_timer_init_cfg(cyhal_timer_t *obj, const cyhal_timer_configurator_t *cfg);
  199. /** Deinitialize the timer/counter object
  200. *
  201. * @param[in,out] obj The timer/counter object
  202. */
  203. void cyhal_timer_free(cyhal_timer_t *obj);
  204. /** Updates the configuration and counter value of the timer/counter object. <br>
  205. * This function may temporary stop the timer if it is currently running.
  206. * See \ref subsection_timer_snippet_1.
  207. * @param[in] obj The timer/counter object
  208. * @param[in] cfg The configuration of the timer/counter
  209. * @return The status of the configure request
  210. */
  211. cy_rslt_t cyhal_timer_configure(cyhal_timer_t *obj, const cyhal_timer_cfg_t *cfg);
  212. /** Configures the timer frequency.
  213. * \note This is only valid to call if a null clock divider was provided to \ref cyhal_timer_init.
  214. * If a custom clock was provided its frequency should be adjusted directly.
  215. *
  216. * See \ref subsection_timer_snippet_1.
  217. * @param[in] obj The timer/counter object
  218. * @param[in] hz The frequency rate in Hz
  219. * @return The status of the set_frequency request
  220. */
  221. cy_rslt_t cyhal_timer_set_frequency(cyhal_timer_t *obj, uint32_t hz);
  222. /** Starts the timer/counter with the pre-set configuration from \ref cyhal_timer_configure.
  223. * This does not reset the counter. The count value will start from the value that was
  224. * set by the last operation to modify it. See \ref cyhal_timer_configure, and \ref
  225. * cyhal_timer_reset for how the value can be changed. If none of these functions have
  226. * been called, it will start from 0.<br>
  227. * See \ref subsection_timer_snippet_1.
  228. *
  229. * @param[in] obj The timer/counter object
  230. * @return The status of the start request
  231. */
  232. cy_rslt_t cyhal_timer_start(cyhal_timer_t *obj);
  233. /** Stops the timer/counter. Does not reset counter value. <br>
  234. *
  235. * @param[in] obj The timer/counter object
  236. * @return The status of the stop request
  237. */
  238. cy_rslt_t cyhal_timer_stop(cyhal_timer_t *obj);
  239. /** Reset the timer/counter value to the default value set from \ref cyhal_timer_configure.
  240. * If \ref cyhal_timer_configure was never called, this will reset timer/counter value to 0.
  241. * This function may temporary stop the timer. <br>
  242. *
  243. * @param[in] obj The timer/counter object
  244. * @return The status of the reset request
  245. */
  246. cy_rslt_t cyhal_timer_reset(cyhal_timer_t *obj);
  247. /** Reads the current value from the timer/counter <br>
  248. * See \ref subsection_timer_snippet_1.
  249. *
  250. * @param[in] obj The timer/counter object
  251. * @return The current value of the timer/counter
  252. */
  253. uint32_t cyhal_timer_read(const cyhal_timer_t *obj);
  254. /** Register a timer/counter callback handler<br>
  255. *
  256. * This function will be called when one of the events enabled by \ref cyhal_timer_enable_event occurs.
  257. *
  258. * See \ref subsection_timer_snippet_2.
  259. *
  260. * @param[in] obj The timer/counter object
  261. * @param[in] callback The callback handler which will be invoked when the event occurs
  262. * @param[in] callback_arg Generic argument that will be provided to the callback when called
  263. */
  264. void cyhal_timer_register_callback(cyhal_timer_t *obj, cyhal_timer_event_callback_t callback, void *callback_arg);
  265. /** Configure timer/counter event enablement <br>
  266. *
  267. * When an enabled event occurs, the function specified by \ref cyhal_timer_register_callback will be called.
  268. *
  269. * See \ref subsection_timer_snippet_2.
  270. *
  271. * @param[in] obj The timer/counter object
  272. * @param[in] event The timer/counter event type
  273. * @param[in] intr_priority The priority for NVIC interrupt events
  274. * @param[in] enable True to turn on interrupts, False to turn off
  275. */
  276. void cyhal_timer_enable_event(cyhal_timer_t *obj, cyhal_timer_event_t event, uint8_t intr_priority, bool enable);
  277. /** Connects a source signal and configures and enables a timer event to be
  278. * triggered from that signal. These timer events can be configured
  279. * independently and connect to the same or different source signals.
  280. * @note For "edge" signals, this function will default to rising edge. To control the edge type,
  281. * use @ref cyhal_timer_connect_digital2
  282. *
  283. * @param[in] obj Timer obj
  284. * @param[in] source Source signal obtained from another driver's cyhal_<PERIPH>_enable_output
  285. * @param[in] signal The timer input signal
  286. * @return The current status of the connection
  287. * */
  288. cy_rslt_t cyhal_timer_connect_digital(cyhal_timer_t *obj, cyhal_source_t source, cyhal_timer_input_t signal);
  289. /** Connects a source signal and configures and enables a timer event to be
  290. * triggered from that signal with a configurable edge type. These timer events
  291. * can be configured independently and connect to the same or different source signals.
  292. *
  293. * @param[in] obj Timer obj
  294. * @param[in] source Source signal obtained from another driver's cyhal_<PERIPH>_enable_output
  295. * @param[in] signal The timer input signal
  296. * @param[in] edge_type The edge type that should trigger the event. This must be consistent with the
  297. * edge type of `source`. If `source` produces a "level" signal, the only valid
  298. * value is @ref CYHAL_EDGE_TYPE_LEVEL. If `source` produces an "edge" signal, then
  299. * @ref CYHAL_EDGE_TYPE_LEVEL is not a valid value.
  300. * @return The current status of the connection
  301. * */
  302. 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);
  303. /** Enables the specified output signal from a tcpwm that will be triggered
  304. * when the corresponding event occurs. Multiple output signals can be
  305. * configured simultaneously.
  306. *
  307. * @param[in] obj Timer obj
  308. * @param[in] signal The timer output signal
  309. * @param[out] source Pointer to user-allocated source signal object which
  310. * will be initialized by enable_output. \p source should be passed to
  311. * (dis)connect_digital functions to (dis)connect the associated endpoints.
  312. * @return The current status of the output enable
  313. * */
  314. cy_rslt_t cyhal_timer_enable_output(cyhal_timer_t *obj, cyhal_timer_output_t signal, cyhal_source_t *source);
  315. /** Disconnects a source signal and disables the timer event.
  316. *
  317. * @param[in] obj Timer obj
  318. * @param[in] source Source signal from cyhal_<PERIPH>_enable_output to disable
  319. * @param[in] signal The timer input signal
  320. * @return The status of the disconnection
  321. * */
  322. cy_rslt_t cyhal_timer_disconnect_digital(cyhal_timer_t *obj, cyhal_source_t source, cyhal_timer_input_t signal);
  323. /** Disables the specified output signal from a timer.
  324. *
  325. * @param[in] obj Timer obj
  326. * @param[in] signal The timer output signal
  327. * @return The status of the output disable
  328. * */
  329. cy_rslt_t cyhal_timer_disable_output(cyhal_timer_t *obj, cyhal_timer_output_t signal);
  330. #if defined(__cplusplus)
  331. }
  332. #endif
  333. #ifdef CYHAL_TIMER_IMPL_HEADER
  334. #include CYHAL_TIMER_IMPL_HEADER
  335. #endif /* CYHAL_TIMER_IMPL_HEADER */
  336. /** \} group_hal_timer */