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