1 /***************************************************************************//**
2 * \file cyhal_lptimer.h
3 *
4 * \brief
5 * Provides a high level interface for interacting with the Infineon Low-Power Timer.
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 /**
31 * \addtogroup group_hal_lptimer LPTimer (Low-Power Timer)
32 * \ingroup group_hal
33 * \{
34 * High level interface for interacting with the low-power timer (LPTimer).
35 *
36 * LPTimer can operate in all possible low power modes. It can be used either to measure timing between events, or to perform
37 * some action after a specified interval of time.
38 * \section subsection_lptimer_features Features
39 * * Wake the device up from deepsleep
40 * * Configurable to create a free-running timer or generate periodic interrupts.
41 * * Configurable to update the match value of an already configured LPTimer set up to generate an interrupt on match.
42 * * Used for measuring time between events in free-running mode.
43 *
44 * \section subsection_lptimer_quickstart Quick Start
45 *
46 * \ref cyhal_lptimer_init can be used for a LPTimer initialization which resets all the clocking and prescaler registers, along with disabling the compare interrupt.
47 *
48 * See \ref subsection_lptimer_snippet_2.
49 *
50 * \section subsection_lptimer_snippets Code snippets
51 *
52 * \subsection subsection_lptimer_snippet_1 Snippet 1: LPTimer initialization with Default configuration
53 * The following snippet initializes a LPTimer in free running mode.
54 * \snippet hal_lptimer.c snippet_cyhal_lptimer_simple_init_def
55 *
56 * \subsection subsection_lptimer_snippet_2 Snippet 2: LPTimer interrupts
57 * The following snippet initializes a LPTimer and uses \ref cyhal_lptimer_set_match() to trigger an interrupt
58 * on match. Subsequent interrupts can be triggered at required times using \ref cyhal_lptimer_set_delay() called from the ISR.
59 * \snippet hal_lptimer.c snippet_cyhal_lptimer_interrupt
60 */
61 
62 #pragma once
63 
64 #include <stdint.h>
65 #include <stdbool.h>
66 #include "cy_result.h"
67 #include "cyhal_hw_types.h"
68 
69 #if defined(__cplusplus)
70 extern "C" {
71 #endif
72 
73 /** \addtogroup group_hal_results_lptimer LPTimer HAL Results
74  *  LPTimer specific return codes
75  *  \ingroup group_hal_results
76  *  \{ *//**
77  */
78 
79 /** Failed to configure power management callback */
80 #define CYHAL_LPTIMER_RSLT_ERR_PM_CALLBACK              \
81     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_LPTIMER, 0))
82 
83 /** Failed to execute not supported API */
84 #define CYHAL_LPTIMER_RSLT_ERR_NOT_SUPPORTED            \
85     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_LPTIMER, 1))
86 
87 /** Timer is not enabled or it is not clocked */
88 #define CYHAL_LPTIMER_RSLT_ERR_DISABLED            \
89     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_LPTIMER, 2))
90 
91 /** Bad argument. eg: null pointer */
92 #define CYHAL_LPTIMER_RSLT_ERR_BAD_ARGUMENT            \
93     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_LPTIMER, 3))
94 
95 /**
96  * \}
97  */
98 
99 /** LPTimer Information */
100 typedef struct cyhal_lptimer_info {
101     uint32_t frequency_hz;      /**< Operating clock frequency the LPTimer is running on. */
102     uint8_t  min_set_delay;     /**< Minimum permitted value for the delay parameter in \ref cyhal_lptimer_set_delay. */
103     uint32_t max_counter_value; /**< Maximum value of the counter. */
104 } cyhal_lptimer_info_t;
105 
106 /** LPTimer interrupt triggers */
107 typedef enum {
108     CYHAL_LPTIMER_COMPARE_MATCH,
109 } cyhal_lptimer_event_t;
110 
111 /** Handler for LPTimer interrupts */
112 typedef void (*cyhal_lptimer_event_callback_t)(void *callback_arg, cyhal_lptimer_event_t event);
113 
114 /** Initialize the LPTimer
115  *
116  * Initialize or re-initialize the LPTimer. This resets all the
117  * clocking and prescaler registers, along with disabling
118  * the compare interrupt. Refer to the BSP for the clock source
119  * for the LPTimer.
120  *
121  * @param[out] obj  Pointer to an LPTimer object. The caller must allocate the memory
122  *  for this object but the init function will initialize its contents.
123  * @return The status of the init request. On success it returns \ref CY_RSLT_SUCCESS.
124  */
125 
126 cy_rslt_t cyhal_lptimer_init(cyhal_lptimer_t *obj);
127 
128 /** Deinitialize the LPTimer
129  *
130  * Powers down the LPTimer.
131  * After calling this function no other LPTimer functions should be called except
132  * cyhal_lptimer_init(). Calling any function other than init after freeing is
133  * undefined.
134  *
135  * @param[inout] obj The LPTimer object
136  */
137 void cyhal_lptimer_free(cyhal_lptimer_t *obj);
138 
139 /** Reload/Reset the Low-Power timer.
140  *
141  * @param[in] obj   The LPTimer object
142  * @return The status of the reload request. On success it returns \ref CY_RSLT_SUCCESS.
143  */
144 cy_rslt_t cyhal_lptimer_reload(cyhal_lptimer_t *obj);
145 
146 /** Deprecated. Call cyhal_lptimer_set_match instead. */
147 #define cyhal_lptimer_set_time cyhal_lptimer_set_match
148 
149 /** Update the match/compare value
150  *
151  * Update the match value of an already configured LPTimer set up
152  * to generate an interrupt on match. Note that this function does not
153  * reinitialize the counter or the associated peripheral initialization
154  * sequence.
155  * \note This does not reset the counter.
156  *
157  * @param[in] obj   The LPTimer object
158  * @param[in] ticks The tick value to match
159  *
160  * @return The status of the set_match request. On success it returns \ref CY_RSLT_SUCCESS.
161  */
162 cy_rslt_t cyhal_lptimer_set_match(cyhal_lptimer_t *obj, uint32_t ticks);
163 
164 /** Update the match/compare value
165  *
166  * Update the match value of an already configured LPTimer set up
167  * to generate an interrupt on match delay from the current counter value.
168  * Note that this function does not reinitialize the counter or the
169  * associated peripheral initialization
170  * sequence.
171  * \note This does not reset the counter.
172  *
173  * @param[in] obj   The LPTimer object
174  * @param[in] delay The ticks to wait. The minimum permitted delay value can be
175  *                  queried using \ref cyhal_lptimer_get_info
176  *
177  * @return The status of the set_match request. On success it returns \ref CY_RSLT_SUCCESS.
178  */
179 cy_rslt_t cyhal_lptimer_set_delay(cyhal_lptimer_t *obj, uint32_t delay);
180 
181 /** Read the current tick
182  *
183  * If no rollover has occurred, the seconds passed since cyhal_lptimer_init() or cyhal_lptimer_set_time()
184  * was called can be found by dividing the ticks returned by this function
185  * by the frequency of the source clock (Refer to BSP Settings section in the kit's BSP API Reference Manual for details on the clock source for LPTimer).
186  *
187  * @param[in] obj    The LPTimer object
188  * @return The timer's timer value in ticks
189  */
190 uint32_t cyhal_lptimer_read(const cyhal_lptimer_t *obj);
191 
192 /** Register a LPTimer match event handler
193  *
194  * This function will be called when one of the events enabled by \ref cyhal_lptimer_enable_event occurs.
195  *
196  * @param[in] obj          The LPTimer object
197  * @param[in] callback     The callback handler which will be invoked when the interrupt triggers
198  * @param[in] callback_arg Generic argument that will be provided to the handler when called
199  */
200 void cyhal_lptimer_register_callback(cyhal_lptimer_t *obj, cyhal_lptimer_event_callback_t callback, void *callback_arg);
201 
202 /** Configure and Enable/Disable the LPTimer events
203  *
204  * When an enabled event occurs, the function specified by \ref cyhal_lptimer_register_callback will be called.
205  *
206  * @param[in] obj            The LPTimer object
207  * @param[in] event          The LPTimer event type
208  * @param[in] intr_priority  The priority for NVIC interrupt events
209  * @param[in] enable         True to turn on event, False to turn off
210  */
211 void cyhal_lptimer_enable_event(cyhal_lptimer_t *obj, cyhal_lptimer_event_t event, uint8_t intr_priority, bool enable);
212 
213 /** Manually trigger the LPTimer interrupt.
214  *
215  * @param[in] obj      The LPTimer object
216  */
217 void cyhal_lptimer_irq_trigger(cyhal_lptimer_t *obj);
218 
219 /** Get information about the LPTimer.
220  *
221  * Provides information such as operating frequency, etc.
222  *
223  * @param[in]   obj     The LPTimer object.
224  * @param[out]  info    Information about the LPtimer.
225  */
226 void cyhal_lptimer_get_info(cyhal_lptimer_t *obj, cyhal_lptimer_info_t *info);
227 
228 #if defined(__cplusplus)
229 }
230 #endif
231 
232 #ifdef CYHAL_LPTIMER_IMPL_HEADER
233 #include CYHAL_LPTIMER_IMPL_HEADER
234 #endif /* CYHAL_LPTIMER_IMPL_HEADER */
235 
236 /** \} group_hal_lptimer */
237