PIC24 Support Libraries
pic24_timer.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 
31 
32 // Documentation for this file. If the \file tag isn't present,
33 // this file won't be documented.
34 /** \file
35  * To do.
36  */
37 
38 #include "pic24_timer.h"
39 #include "pic24_clockfreq.h"
40 #include "pic24_unittest.h"
41 #include "pic24_util.h"
42 
43 
44 #ifndef _NOFLOAT
45 /** Converts milliseconds to 16-bit timer ticks.
46  * \param u16_ms Time, in milliseconds, to convert to ticks
47  * \param u16_pre Prescale set for this timer. Note that
48  * \ref getTimerPrescale can easily determine
49  * this.
50  * \return Timer ticks corresponding to the given number of
51  * milliseconds.
52  */
53 uint16_t msToU16Ticks(uint16_t u16_ms, uint16_t u16_pre) {
54  // Use a float internally for precision purposes to accomodate wide range of FCY, u16_pre
55  float f_ticks = FCY;
56  uint16_t u16_ticks;
57  f_ticks = (f_ticks*u16_ms)/u16_pre/1E3;
58  ASSERT(f_ticks < 65535.5);
59  u16_ticks = roundFloatToUint16(f_ticks); //back to integer
60  return u16_ticks;
61 }
62 
63 /** Converts microseconds to 16-bit timer ticks.
64  * \param u16_us Time, in microseconds, to convert to ticks
65  * \param u16_pre Prescale set for this timer. Note that
66  * \ref getTimerPrescale can easily determine
67  * this.
68  * \return Timer ticks corresponding to the given number of
69  * microseconds.
70  */
71 uint16_t usToU16Ticks(uint16_t u16_us, uint16_t u16_pre) {
72  // Use a float internally for precision purposes to accomodate wide range of FCY, u16_pre
73  float f_ticks = FCY;
74  uint16_t u16_ticks;
75  f_ticks = (f_ticks*u16_us)/u16_pre/1E6;
76  ASSERT(f_ticks < 65535.5);
77  u16_ticks = roundFloatToUint16(f_ticks); //back to integer
78  return u16_ticks;
79 
80 }
81 
82 /** Converts microseconds to 32-bit timer ticks.
83  * \param u32_us Time, in microseconds, to convert to ticks
84  * \param u16_pre Prescale set for this timer. Note that
85  * \ref getTimerPrescale can easily determine
86  * this.
87  * \return Timer ticks corresponding to the given number of
88  * microseconds.
89  */
90 uint32_t usToU32Ticks(uint32_t u32_us, uint16_t u16_pre) {
91  // Use a float internally for precision purposes to accomodate wide range of FCY, u16_pre.
92  float f_ticks = FCY;
93  uint32_t u32_ticks;
94  f_ticks = (f_ticks*u32_us)/u16_pre/1E6;
95  u32_ticks = roundFloatToUint32(f_ticks); //back to integer
96  return u32_ticks;
97 }
98 
99 
100 
101 /** Converts timer ticks to milliseconds
102  * \param u32_ticks Timer ticks
103  * \param u16_tmrPre Timer prescale value
104  * \return time in milliseconds
105  */
106 uint32_t ticksToMs(uint32_t u32_ticks, uint16_t u16_tmrPre) {
107  // Because of the wide range of the numbers, use a float for precision.
108  float f_ticks;
109  uint32_t u32_timeMs;
110 
111  f_ticks = u32_ticks; //convert to float
112  f_ticks = ((f_ticks*u16_tmrPre)/FCY)*1E3;
113  u32_timeMs = roundFloatToUint32(f_ticks); //back to int32_t
114  return u32_timeMs;
115 }
116 
117 
118 /** Converts timer ticks to microseconds
119  * \param u32_ticks Timer ticks
120  * \param u16_tmrPre Timer prescale value
121  * \return time in microseconds
122  */
123 uint32_t ticksToUs(uint32_t u32_ticks, uint16_t u16_tmrPre) {
124  // Because of the wide range of the numbers, use a float for precision.
125  float f_ticks;
126  uint32_t u32_timeUs;
127 
128  f_ticks = u32_ticks; //convert to float
129  f_ticks = ((f_ticks*u16_tmrPre)/FCY)*1E6;
130  u32_timeUs = roundFloatToUint32(f_ticks); //back to int32_t
131  return u32_timeUs;
132 }
133 
134 /** Converts timer ticks to nanoseconds
135  * \param u32_ticks Timer ticks
136  * \param u16_tmrPre Timer prescale value
137  * \return time in nanoseconds
138  */
139 uint32_t ticksToNs(uint32_t u32_ticks, uint16_t u16_tmrPre) {
140  //because of the wide range of the numbers, use a float for precision
141  float f_ticks;
142  uint32_t u32_timeNs;
143 
144  f_ticks = u32_ticks; //convert to float
145  f_ticks = ((f_ticks*u16_tmrPre)/FCY)*1E9;
146  u32_timeNs = roundFloatToUint32(f_ticks); //back to int32_t
147  return u32_timeNs;
148 }
149 #endif // #ifndef _NOFLOAT
150 
151 /** Given the TCKPS bitfield, return the timer prescale encoded
152  * by these bits. Use \ref getTimerPrescale as a convenient
153  * way to extract the TCKPS bitfield from a TxCONbits SFT
154  * then call this function.
155  * \param u8_TCKPS TCKPS bitfield from the timer in question
156  * \return Prescale value.
157  */
158 uint16_t getTimerPrescaleBits(uint8_t u8_TCKPS) {
159  const uint16_t au16_prescaleValue[] = { 1, 8, 64, 256 };
160  ASSERT(u8_TCKPS <= 3);
161  return au16_prescaleValue[u8_TCKPS];
162 }
163 
164 /** Computes delta ticks between two Timer register captures
165  * Assumes long time interval and thus has a parameter for tracking timer overflows
166  * \param u16_start start tick
167  * \param u16_end end tick
168  * \param u16_tmrPR Timer period register
169  * \param u16_oflows number of timer overflows
170  * \return delta ticks
171  */
172 uint32_t computeDeltaTicksLong(uint16_t u16_start, uint16_t u16_end, uint16_t u16_tmrPR, uint16_t u16_oflows) {
173  uint32_t u32_deltaTicks;
174  if (u16_oflows == 0) u32_deltaTicks = u16_end - u16_start;
175  else {
176  //compute ticks from start to timer overflow
177  u32_deltaTicks = (u16_tmrPR + 1) - u16_start;
178  //add ticks due to overflows = (overflows -1) * ticks_per_overflow
179  u32_deltaTicks += ((((uint32_t) u16_oflows)- 1) * (((uint32_t)u16_tmrPR) + 1)) ;
180  //now add in the delta due to the last capture
181  u32_deltaTicks += u16_end;
182  }
183  return u32_deltaTicks;
184 }
185 
186 /** Computes delta ticks between two Timer register captures
187  * Assumes the delta time does not exceeds the timer period
188  * \param u16_start start tick
189  * \param u16_end end tick
190  * \param u16_tmrPR Timer period register
191  * \return delta ticks
192  */
193 uint16_t computeDeltaTicks(uint16_t u16_start, uint16_t u16_end, uint16_t u16_tmrPR) {
194  uint16_t u16_deltaTicks;
195  if (u16_end >= u16_start) u16_deltaTicks = u16_end - u16_start;
196  else {
197  //compute ticks from start to timer overflow
198  u16_deltaTicks = (u16_tmrPR + 1) - u16_start;
199  //now add in the delta from overflow to u16_end
200  u16_deltaTicks += u16_end;
201  }
202  return u16_deltaTicks;
203 }
uint32_t ticksToMs(uint32_t u32_ticks, uint16_t u16_tmrPre)
Definition: pic24_timer.c:106
uint32_t computeDeltaTicksLong(uint16_t u16_start, uint16_t u16_end, uint16_t u16_tmrPR, uint16_t u16_oflows)
Definition: pic24_timer.c:172
uint32_t roundFloatToUint32(float f_x)
Definition: pic24_util.c:448
Configures the system clock.
uint16_t getTimerPrescaleBits(uint8_t u8_TCKPS)
Definition: pic24_timer.c:158
uint16_t computeDeltaTicks(uint16_t u16_start, uint16_t u16_end, uint16_t u16_tmrPR)
Definition: pic24_timer.c:193
uint16_t msToU16Ticks(uint16_t u16_ms, uint16_t u16_pre)
Definition: pic24_timer.c:53
#define FCY
uint32_t usToU32Ticks(uint32_t u32_us, uint16_t u16_pre)
Definition: pic24_timer.c:90
uint32_t ticksToUs(uint32_t u32_ticks, uint16_t u16_tmrPre)
Definition: pic24_timer.c:123
#define ASSERT(test)
uint32_t ticksToNs(uint32_t u32_ticks, uint16_t u16_tmrPre)
Definition: pic24_timer.c:139
uint16_t roundFloatToUint16(float f_x)
Definition: pic24_util.c:460
unsigned char uint8_t
An abbreviation for an 8-bit unsigned integer.
Definition: dataXferImpl.h:194
uint16_t usToU16Ticks(uint16_t u16_us, uint16_t u16_pre)
Definition: pic24_timer.c:71