1 /******************************************************************************
2  *  Filename:       systick.h
3  *
4  *  Description:    Prototypes for the SysTick driver.
5  *
6  *  Copyright (c) 2022 Texas Instruments Incorporated
7  *
8  *  Redistribution and use in source and binary forms, with or without
9  *  modification, are permitted provided that the following conditions are met:
10  *
11  *  1) Redistributions of source code must retain the above copyright notice,
12  *     this list of conditions and the following disclaimer.
13  *
14  *  2) Redistributions in binary form must reproduce the above copyright notice,
15  *     this list of conditions and the following disclaimer in the documentation
16  *     and/or other materials provided with the distribution.
17  *
18  *  3) Neither the name of the copyright holder nor the names of its
19  *     contributors may be used to endorse or promote products derived from this
20  *     software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  *  POSSIBILITY OF SUCH DAMAGE.
33  *
34  ******************************************************************************/
35 
36 #ifndef __SYSTICK_H__
37 #define __SYSTICK_H__
38 
39 //*****************************************************************************
40 //
41 //! \addtogroup system_cpu_group
42 //! @{
43 //! \addtogroup systick_api
44 //! @{
45 //
46 //*****************************************************************************
47 
48 //*****************************************************************************
49 //
50 // If building with a C++ compiler, make all of the definitions in this header
51 // have a C binding.
52 //
53 //*****************************************************************************
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 #include <stdbool.h>
59 #include <stdint.h>
60 #include "../inc/hw_types.h"
61 #include "../inc/hw_ints.h"
62 #include "../inc/hw_memmap.h"
63 #include "../inc/hw_systick.h"
64 #include "debug.h"
65 #include "interrupt.h"
66 
67 //*****************************************************************************
68 //
69 // API Functions and Prototypes
70 //
71 //*****************************************************************************
72 
73 //*****************************************************************************
74 //
75 //! \brief Enables the SysTick counter.
76 //!
77 //! This will start the SysTick counter. If an interrupt handler has been
78 //! registered, it will be called when the SysTick counter rolls over.
79 //!
80 //! \note Calling this function will cause the SysTick counter to (re)commence
81 //! counting from its current value. The counter is not automatically reloaded
82 //! with the period as specified in a previous call to \ref SysTickSetPeriod().
83 //! If an immediate reload is required, the SYSTICK_O_CVR register must be
84 //! written to force this. Any write to this register clears the SysTick
85 //! counter to 0 and will cause a reload with the supplied period on the next
86 //! clock.
87 //!
88 //! \return None
89 //
90 //*****************************************************************************
SysTickEnable(void)91 __STATIC_INLINE void SysTickEnable(void)
92 {
93     // Enable SysTick.
94     HWREG(SYSTICK_BASE + SYSTICK_O_CSR) |= (SYSTICK_CSR_CLKSOURCE | SYSTICK_CSR_ENABLE);
95 }
96 
97 //*****************************************************************************
98 //
99 //! \brief Disables the SysTick counter.
100 //!
101 //! This will stop the SysTick counter. If an interrupt handler has been
102 //! registered, it will no longer be called until SysTick is restarted.
103 //!
104 //! \return None
105 //
106 //*****************************************************************************
SysTickDisable(void)107 __STATIC_INLINE void SysTickDisable(void)
108 {
109     // Disable SysTick.
110     HWREG(SYSTICK_BASE + SYSTICK_O_CSR) &= ~(SYSTICK_CSR_ENABLE);
111 }
112 
113 //*****************************************************************************
114 //
115 //! \brief Registers an interrupt handler for the SysTick interrupt in the dynamic interrupt table.
116 //!
117 //! \note Only use this function if you want to use the dynamic vector table (in SRAM)!
118 //!
119 //! This function registers a function as the interrupt handler for a specific
120 //! interrupt and enables the corresponding interrupt in the interrupt controller.
121 //!
122 //! \param pfnHandler is a pointer to the function to be called when the
123 //! SysTick interrupt occurs.
124 //!
125 //! \return None
126 //!
127 //! \sa \ref IntRegister() for important information about registering interrupt
128 //! handlers.
129 //
130 //*****************************************************************************
SysTickRegisterInt(void (* pfnHandler)(void))131 __STATIC_INLINE void SysTickRegisterInt(void (*pfnHandler)(void))
132 {
133     // Register the interrupt handler, returning an error if an error occurs.
134     IntRegister(INT_SYSTICK, pfnHandler);
135 
136     // Enable the SysTick interrupt.
137     HWREG(SYSTICK_BASE + SYSTICK_O_CSR) |= SYSTICK_CSR_TICKINT;
138 }
139 
140 //*****************************************************************************
141 //
142 //! \brief Unregisters the interrupt handler for the SysTick interrupt in the dynamic interrupt table.
143 //!
144 //! This function will clear the handler to be called when a SysTick interrupt
145 //! occurs.
146 //!
147 //! \return None
148 //!
149 //! \sa \ref IntRegister() for important information about registering interrupt
150 //! handlers.
151 //
152 //*****************************************************************************
SysTickUnregisterInt(void)153 __STATIC_INLINE void SysTickUnregisterInt(void)
154 {
155     // Disable the SysTick interrupt.
156     HWREG(SYSTICK_BASE + SYSTICK_O_CSR) &= ~(SYSTICK_CSR_TICKINT);
157 
158     // Unregister the interrupt handler.
159     IntUnregister(INT_SYSTICK);
160 }
161 
162 //*****************************************************************************
163 //
164 //! \brief Enables the SysTick interrupt.
165 //!
166 //! This function will enable the SysTick interrupt, allowing it to be
167 //! reflected to the processor.
168 //!
169 //! \note The SysTick interrupt handler does not need to clear the SysTick
170 //! interrupt source as this is done automatically when the interrupt handler
171 //! is called.
172 //!
173 //! \return None
174 //
175 //*****************************************************************************
SysTickEnableInt(void)176 __STATIC_INLINE void SysTickEnableInt(void)
177 {
178     // Enable the SysTick interrupt.
179     HWREG(SYSTICK_BASE + SYSTICK_O_CSR) |= SYSTICK_CSR_TICKINT;
180 }
181 
182 //*****************************************************************************
183 //
184 //! \brief Disables the SysTick interrupt.
185 //!
186 //! This function will disable the SysTick interrupt, preventing it from being
187 //! reflected to the processor.
188 //!
189 //! \return None
190 //
191 //*****************************************************************************
SysTickDisableInt(void)192 __STATIC_INLINE void SysTickDisableInt(void)
193 {
194     // Disable the SysTick interrupt.
195     HWREG(SYSTICK_BASE + SYSTICK_O_CSR) &= ~(SYSTICK_CSR_TICKINT);
196 }
197 
198 //*****************************************************************************
199 //
200 //! \brief Sets the period of the SysTick counter.
201 //!
202 //! This function sets the rate at which the SysTick counter wraps; this
203 //! equals to the number of processor clocks between interrupts.
204 //!
205 //! \note Calling this function does not cause the SysTick counter to reload
206 
207 //! immediately. If an immediate reload is required, the SYSTICK_O_CVR
208 //! register must be written. Any write to this register clears the SysTick
209 //! counter to 0 and will cause a reload with the \c period supplied here
210 //! on the next clock after the SysTick is enabled.
211 //!
212 //! \param period is the number of clock ticks in each period of the
213 //! SysTick counter; must be between 1 and 16,777,216 (0x1000000), both included.
214 //!
215 //! \return None
216 //
217 //*****************************************************************************
SysTickSetPeriod(uint32_t period)218 __STATIC_INLINE void SysTickSetPeriod(uint32_t period)
219 {
220     // Check the arguments.
221     ASSERT((period > 0) && (period <= 16777216));
222 
223     // Set the period of the SysTick counter.
224     HWREG(SYSTICK_BASE + SYSTICK_O_RVR) = period - 1;
225 }
226 
227 //*****************************************************************************
228 //
229 //! \brief Gets the period of the SysTick counter.
230 //!
231 //! This function returns the rate at which the SysTick counter wraps; this
232 //! equals to the number of processor clocks between interrupts.
233 //!
234 //! \return Returns the period of the SysTick counter.
235 //
236 //*****************************************************************************
SysTickGetPeriod(void)237 __STATIC_INLINE uint32_t SysTickGetPeriod(void)
238 {
239     // Return the period of the SysTick counter.
240     return (HWREG(SYSTICK_BASE + SYSTICK_O_RVR) + 1);
241 }
242 
243 //*****************************************************************************
244 //
245 //! \brief Gets the current value of the SysTick counter.
246 //!
247 //! This function returns the current value of the SysTick counter; this will
248 //! be a value between the (period - 1) and zero, both included.
249 //!
250 //! \return Returns the current value of the SysTick counter
251 //
252 //*****************************************************************************
SysTickGetValue(void)253 __STATIC_INLINE uint32_t SysTickGetValue(void)
254 {
255     // Return the current value of the SysTick counter.
256     return (HWREG(SYSTICK_BASE + SYSTICK_O_CVR));
257 }
258 
259 //*****************************************************************************
260 //
261 // Mark the end of the C bindings section for C++ compilers.
262 //
263 //*****************************************************************************
264 #ifdef __cplusplus
265 }
266 #endif
267 
268 //*****************************************************************************
269 //
270 //! Close the Doxygen group
271 //! @}
272 //! @}
273 //
274 //*****************************************************************************
275 
276 #endif // __SYSTICK_H__
277