CLKDIV-Durchlauf für Sync zum Messen.
[hackover2013-badge-firmware.git] / core / systick / systick.c
1 /**************************************************************************/
2 /*!
3 @file systick.c
4 @author K. Townsend (microBuilder.eu)
5 @date 22 March 2010
6 @version 0.10
7
8 @section DESCRIPTION
9
10 Controls the 24-bit 'system tick' clock, which can be used as a
11 generic timer or to control time sharing with an embedded real-time
12 operating system (such as FreeRTOS).
13
14 @section Example
15
16 @code
17 #include "core/cpu/cpu.h"
18 #include "core/systick/systick.h"
19
20 void main (void)
21 {
22 cpuInit();
23
24 // Start systick timer with one tick every 10ms
25 systickInit(10);
26
27 while(1)
28 {
29 }
30 }
31 @endcode
32
33 @section LICENSE
34
35 Software License Agreement (BSD License)
36
37 Copyright (c) 2010, microBuilder SARL
38 All rights reserved.
39
40 Redistribution and use in source and binary forms, with or without
41 modification, are permitted provided that the following conditions are met:
42 1. Redistributions of source code must retain the above copyright
43 notice, this list of conditions and the following disclaimer.
44 2. Redistributions in binary form must reproduce the above copyright
45 notice, this list of conditions and the following disclaimer in the
46 documentation and/or other materials provided with the distribution.
47 3. Neither the name of the copyright holders nor the
48 names of its contributors may be used to endorse or promote products
49 derived from this software without specific prior written permission.
50
51 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
52 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
55 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62 /**************************************************************************/
63
64 #include "systick.h"
65
66 #ifdef CFG_SDCARD
67 #include "drivers/fatfs/diskio.h"
68 volatile uint32_t fatTicks = 0;
69 #endif
70
71 volatile uint32_t systickTicks = 0; // 1ms tick counter
72 volatile uint32_t systickRollovers = 0;
73
74 /**************************************************************************/
75 /*!
76 @brief Systick interrupt handler
77 */
78 /**************************************************************************/
79 void SysTick_Handler (void)
80 {
81 systickTicks++;
82
83 // Increment rollover counter
84 if (systickTicks == 0xFFFFFFFF) systickRollovers++;
85
86 #ifdef CFG_SDCARD
87 fatTicks++;
88 if (fatTicks == 10)
89 {
90 fatTicks = 0;
91 disk_timerproc();
92 }
93 #endif
94 }
95
96 /**************************************************************************/
97 /*!
98 @brief Configures the systick timer
99
100 @param[in] ticks
101 The number of clock cycles between each tick of the
102 systick timer. for example, 'CFG_CPU_CCLK / 1000' =
103 1 millisecond. This value must not exceed 0x00FFFFFF.
104 */
105 /**************************************************************************/
106 static uint32_t systickConfig(uint32_t ticks)
107 {
108 // Check if 'ticks' is greater than maximum value
109 if (ticks > SYSTICK_STRELOAD_MASK)
110 {
111 return (1);
112 }
113
114 // Reset counter
115 systickTicks = 0;
116
117 // Set reload register
118 SYSTICK_STRELOAD = (ticks & SYSTICK_STRELOAD_MASK) - 1;
119
120 // Load the systick counter value
121 SYSTICK_STCURR = 0;
122
123 // Enable systick IRQ and timer
124 SYSTICK_STCTRL = SYSTICK_STCTRL_CLKSOURCE |
125 SYSTICK_STCTRL_TICKINT |
126 SYSTICK_STCTRL_ENABLE;
127
128 return (0);
129 }
130
131 /**************************************************************************/
132 /*!
133 @brief Initialises the systick timer
134
135 @param[in] delayMs
136 The number of milliseconds between each tick of the systick
137 timer.
138
139 @note The shortest possible delay is 1 millisecond, which will
140 allow fine grained delays, but will cause more load on the
141 system than a 10mS delay. The resolution of the systick
142 timer needs to be balanced with the amount of processing
143 time you can spare. The delay should really only be set
144 to 1 mS if you genuinely have a need for 1mS delays,
145 otherwise a higher value like 5 or 10 mS is probably
146 more appropriate.
147 */
148 /**************************************************************************/
149 void systickInit (uint32_t delayMs)
150 {
151 systickConfig ((CFG_CPU_CCLK / 1000) * delayMs);
152 }
153
154 /**************************************************************************/
155 /*!
156 @brief Causes a blocking delay for 'delayTicks' ticks on the
157 systick timer. For example: systickDelay(100) would cause
158 a blocking delay for 100 ticks of the systick timer.
159
160 @param[in] delayTicks
161 The number of systick ticks to cause a blocking delay for
162
163 @Note This function takes into account the fact that the tick
164 counter may eventually roll over to 0 once it reaches
165 0xFFFFFFFF.
166 */
167 /**************************************************************************/
168 void systickDelay (uint32_t delayTicks)
169 {
170 uint32_t curTicks;
171 curTicks = systickTicks;
172
173 // Make sure delay is at least 1 tick in case of division, etc.
174 if (delayTicks == 0) delayTicks = 1;
175
176 if (curTicks > 0xFFFFFFFF - delayTicks)
177 {
178 // Rollover will occur during delay
179 while (systickTicks >= curTicks)
180 {
181 while (systickTicks < (delayTicks - (0xFFFFFFFF - curTicks)));
182 }
183 }
184 else
185 {
186 while ((systickTicks - curTicks) < delayTicks);
187 }
188 }
189
190 /**************************************************************************/
191 /*!
192 @brief Returns the current value of the systick timer counter.
193 This value is incremented by one every time an interrupt
194 fires for the systick timer.
195 */
196 /**************************************************************************/
197 uint32_t systickGetTicks(void)
198 {
199 return systickTicks;
200 }
201
202 /**************************************************************************/
203 /*!
204 @brief Returns the current value of the systick timer rollover
205 counter. This value is incremented by one every time the
206 tick counter rolls over from 0xFFFFFFFF to 0.
207 */
208 /**************************************************************************/
209 uint32_t systickGetRollovers(void)
210 {
211 return systickRollovers;
212 }
213
214 /**************************************************************************/
215 /*!
216 @brief Returns the approximate number of seconds that the
217 systick timer has been running.
218 */
219 /**************************************************************************/
220 uint32_t systickGetSecondsActive(void)
221 {
222 uint32_t currentTick = systickTicks;
223 uint32_t rollovers = systickRollovers;
224 uint32_t secsActive = currentTick / (1000 / CFG_SYSTICK_DELAY_IN_MS);
225 secsActive += rollovers * (0xFFFFFFFF / (1000 / CFG_SYSTICK_DELAY_IN_MS));
226
227 return secsActive;
228 }
229
This page took 0.054099 seconds and 5 git commands to generate.