Revision 184
updated time.c and time.h to take multiple functions, somewhat backwards compatible
branches/encoders/code/lib/include/libdragonfly/time.h | ||
---|---|---|
11 | 11 |
#ifndef _TIME_H_ |
12 | 12 |
#define _TIME_H_ |
13 | 13 |
|
14 |
/*Maximum # of functions*/ |
|
15 |
#define MAX_FUNCTIONS 10 |
|
16 |
|
|
17 |
|
|
14 | 18 |
/* Predefined times for prescale_opt in time.c. |
15 | 19 |
To make you own, know that a pulse is 1/16th of a second. You cannot get less than this. To get more, you need |
16 | 20 |
to know how many 16ths of a second are in the time you want. (Time_desired * 16 = prescaler_opt) |
... | ... | |
37 | 41 |
/** @brief Delay execution for the specified time **/ |
38 | 42 |
void delay_ms(int ms) ; |
39 | 43 |
/** @brief Enable the realtime clock **/ |
40 |
void rtc_init(int prescale_opt, void (*rtc_func)(void));
|
|
44 |
int rtc_multi_init(int* prescale_opt, void (*rtc_fun[])(void), int argc);
|
|
41 | 45 |
/** @brief Reset the counter of the realtime clock **/ |
42 | 46 |
void rtc_reset(void); |
43 | 47 |
/** @brief Get the value of the realtime clock. **/ |
44 | 48 |
int rtc_get(void); |
45 | 49 |
|
50 |
int add_function(int prescale_opt, void *rtc_f (void)); |
|
51 |
|
|
52 |
int rtc_init(int prescale_opt, void *rtc_func(void)); |
|
53 |
|
|
46 | 54 |
/** @} **/ |
47 | 55 |
|
48 | 56 |
#endif |
branches/encoders/code/lib/src/libdragonfly/time.c | ||
---|---|---|
18 | 18 |
the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of |
19 | 19 |
256 change it by that multiple. Refer to the time.h file for all possible prescalers. |
20 | 20 |
The interrupt will call a specified function _rtc_func every pulse. |
21 |
All of it has been tested and it works. |
|
21 |
All of it has been tested and it works. |
|
22 |
|
|
23 |
10.29.07 - Andrew |
|
24 |
Modify to accept multiple functions with different time intervals |
|
25 |
|
|
22 | 26 |
|
23 | 27 |
*/ |
24 | 28 |
#include <avr/interrupt.h> |
... | ... | |
26 | 30 |
#include <time.h> |
27 | 31 |
#include <serial.h> |
28 | 32 |
|
29 |
static volatile int _rtc_val = 0; |
|
30 |
static volatile int _rtc_pulse = 0; |
|
31 |
static volatile int _rtc_scale = 32; //Defaults to 1 Second per pulse |
|
32 |
static void (*_rtc_f)(void) = 0; |
|
33 | 33 |
|
34 |
|
|
35 |
static volatile int _rtc_val[MAX_FUNCTIONS]; |
|
36 |
static volatile int _rtc_pulse[MAX_FUNCTIONS]; |
|
37 |
static volatile int _rtc_scale[MAX_FUNCTIONS]; |
|
38 |
static int function_count = 0; //Number of functions |
|
39 |
static void (*_rtc_f[MAX_FUNCTIONS])(void); |
|
40 |
|
|
34 | 41 |
/** |
35 | 42 |
* @defgroup time Time |
36 | 43 |
* @brief Time functions |
... | ... | |
67 | 74 |
* @param rtc_func the function called when the timer is triggered |
68 | 75 |
* |
69 | 76 |
* @see rtc_get, rtc_reset |
70 |
* |
|
71 | 77 |
**/ |
72 |
void rtc_init(int prescale_opt, void (*rtc_func)(void)) { |
|
78 |
|
|
79 |
int rtc_multi_init(int* prescale_opt, void (*rtc_func[])(void), int argc) { |
|
73 | 80 |
|
81 |
//Check that the number of functions doesn't exceed alloted space |
|
82 |
if(argc >= MAX_FUNCTIONS) |
|
83 |
return -1; |
|
84 |
|
|
85 |
function_count = argc; |
|
74 | 86 |
//Clear timer register for Timer 3 |
75 | 87 |
TCNT3 = 0; |
76 | 88 |
|
... | ... | |
94 | 106 |
triggerd. (See page140 in Atmega128 Docs for more information */ |
95 | 107 |
ETIMSK |= _BV(OCIE3A); |
96 | 108 |
|
97 |
/* Store the pointer to the function to be used in the interrupt */ |
|
98 |
_rtc_f = rtc_func; |
|
109 |
|
|
110 |
/* Set number of functions*/ |
|
111 |
function_count = argc; |
|
99 | 112 |
|
100 | 113 |
/* Store how many 1/16ths of a second you want to let by before triggering an interrupt */ |
101 |
_rtc_scale = prescale_opt; |
|
114 |
|
|
115 |
for (int i = 0; i <argc; i++) { |
|
116 |
_rtc_pulse[i] = 0; |
|
117 |
_rtc_val[i] = 0; |
|
118 |
_rtc_f[i] = rtc_func[i]; |
|
119 |
/* Store how many 1/16ths of a second you want to let by before triggering an interrupt */ |
|
120 |
_rtc_scale[i] = prescale_opt[i]; |
|
121 |
} |
|
122 |
return argc-1; |
|
102 | 123 |
} |
103 | 124 |
|
125 |
int add_function(int prescale_opt, void *rtc_func (void)) |
|
126 |
{ |
|
127 |
if(function_count+1>=MAX_FUNCTIONS) |
|
128 |
return -1; |
|
129 |
function_count++; |
|
130 |
_rtc_f[function_count] = rtc_func; |
|
131 |
_rtc_pulse[function_count] = 0; |
|
132 |
_rtc_scale[function_count] = prescale_opt; |
|
133 |
return 1; |
|
134 |
} |
|
135 |
|
|
136 |
int rtc_init(int prescale_opt, void *rtc_func(void)){ |
|
137 |
int temp[] = {prescale_opt}; |
|
138 |
void (*temp2[MAX_FUNCTIONS])(void) = {rtc_func}; |
|
139 |
return rtc_multi_init(temp, temp2, 1); |
|
140 |
} |
|
141 |
|
|
104 | 142 |
/** |
105 | 143 |
* Returns the time elapsed in seconds since the last call to |
106 | 144 |
* rtc_init or rtc_reset. |
... | ... | |
109 | 147 |
* |
110 | 148 |
* @see rtc_init, rtc_reset |
111 | 149 |
**/ |
150 |
/* |
|
112 | 151 |
int rtc_get(void){ |
113 | 152 |
return _rtc_val; |
114 |
} |
|
153 |
}*/
|
|
115 | 154 |
|
116 | 155 |
/** |
117 | 156 |
* Resets the real time clock counter to 0. |
118 | 157 |
* |
119 | 158 |
* @see rtc_init, rtc_get |
120 | 159 |
**/ |
160 |
/* |
|
121 | 161 |
void rtc_reset(void){ |
122 | 162 |
_rtc_val = 0; |
123 |
} |
|
163 |
}*/
|
|
124 | 164 |
|
125 | 165 |
/** @} **/ //end defgroup |
126 | 166 |
|
127 | 167 |
/* Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated. |
128 | 168 |
Bascially, since the pulse is hard set at 1/16s you want to count how many 16ths of a second have passed |
129 | 169 |
and when it reaches the amount of time you want, execute the code. */ |
170 |
|
|
130 | 171 |
SIGNAL(TIMER3_COMPA_vect) { |
131 |
|
|
132 |
if (_rtc_pulse == _rtc_scale) { |
|
133 |
//Increment the real time clock counter |
|
134 |
_rtc_val++; |
|
135 |
|
|
136 |
//Calls the function tied to the real time clock if defined |
|
137 |
if(_rtc_f != 0) |
|
138 |
_rtc_f(); |
|
139 |
|
|
140 |
//Resets the pulse until the next scale is matched |
|
141 |
_rtc_pulse = 0; |
|
142 |
} |
|
143 |
|
|
172 |
for(int functionNumber = 0; functionNumber < function_count; functionNumber++) |
|
173 |
{ |
|
174 |
if (_rtc_pulse[functionNumber] == _rtc_scale[functionNumber]) { |
|
175 |
//Increment the real time clock counter |
|
176 |
_rtc_val[functionNumber]++; |
|
177 |
|
|
178 |
//Calls the function tied to the real time clock if defined |
|
179 |
_rtc_f[functionNumber](); |
|
180 |
|
|
181 |
//Resets the pulse until the next scale is matched |
|
182 |
_rtc_pulse[functionNumber] = 0; |
|
183 |
} |
|
184 |
_rtc_pulse[functionNumber]++; |
|
185 |
} |
|
144 | 186 |
//Updates the amount of pulses seen since the last scale match |
145 |
_rtc_pulse++; |
|
146 | 187 |
|
147 | 188 |
} |
148 |
|
branches/encoders/code/projects/libdragonfly/time.c | ||
---|---|---|
18 | 18 |
the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of |
19 | 19 |
256 change it by that multiple. Refer to the time.h file for all possible prescalers. |
20 | 20 |
The interrupt will call a specified function _rtc_func every pulse. |
21 |
All of it has been tested and it works. |
|
21 |
All of it has been tested and it works. |
|
22 |
|
|
23 |
10.29.07 - Andrew |
|
24 |
Modify to accept multiple functions with different time intervals |
|
25 |
|
|
22 | 26 |
|
23 | 27 |
*/ |
24 | 28 |
#include <avr/interrupt.h> |
... | ... | |
26 | 30 |
#include <time.h> |
27 | 31 |
#include <serial.h> |
28 | 32 |
|
29 |
static volatile int _rtc_val = 0; |
|
30 |
static volatile int _rtc_pulse = 0; |
|
31 |
static volatile int _rtc_scale = 32; //Defaults to 1 Second per pulse |
|
32 |
static void (*_rtc_f)(void) = 0; |
|
33 | 33 |
|
34 |
|
|
35 |
static volatile int _rtc_val[MAX_FUNCTIONS]; |
|
36 |
static volatile int _rtc_pulse[MAX_FUNCTIONS]; |
|
37 |
static volatile int _rtc_scale[MAX_FUNCTIONS]; |
|
38 |
static int function_count = 0; //Number of functions |
|
39 |
static void (*_rtc_f[MAX_FUNCTIONS])(void); |
|
40 |
|
|
34 | 41 |
/** |
35 | 42 |
* @defgroup time Time |
36 | 43 |
* @brief Time functions |
... | ... | |
67 | 74 |
* @param rtc_func the function called when the timer is triggered |
68 | 75 |
* |
69 | 76 |
* @see rtc_get, rtc_reset |
70 |
* |
|
71 | 77 |
**/ |
72 |
void rtc_init(int prescale_opt, void (*rtc_func)(void)) { |
|
78 |
|
|
79 |
int rtc_multi_init(int* prescale_opt, void (*rtc_func[])(void), int argc) { |
|
73 | 80 |
|
81 |
//Check that the number of functions doesn't exceed alloted space |
|
82 |
if(argc >= MAX_FUNCTIONS) |
|
83 |
return -1; |
|
84 |
|
|
85 |
function_count = argc; |
|
74 | 86 |
//Clear timer register for Timer 3 |
75 | 87 |
TCNT3 = 0; |
76 | 88 |
|
... | ... | |
94 | 106 |
triggerd. (See page140 in Atmega128 Docs for more information */ |
95 | 107 |
ETIMSK |= _BV(OCIE3A); |
96 | 108 |
|
97 |
/* Store the pointer to the function to be used in the interrupt */ |
|
98 |
_rtc_f = rtc_func; |
|
109 |
|
|
110 |
/* Set number of functions*/ |
|
111 |
function_count = argc; |
|
99 | 112 |
|
100 | 113 |
/* Store how many 1/16ths of a second you want to let by before triggering an interrupt */ |
101 |
_rtc_scale = prescale_opt; |
|
114 |
|
|
115 |
for (int i = 0; i <argc; i++) { |
|
116 |
_rtc_pulse[i] = 0; |
|
117 |
_rtc_val[i] = 0; |
|
118 |
_rtc_f[i] = rtc_func[i]; |
|
119 |
/* Store how many 1/16ths of a second you want to let by before triggering an interrupt */ |
|
120 |
_rtc_scale[i] = prescale_opt[i]; |
|
121 |
} |
|
122 |
return argc-1; |
|
102 | 123 |
} |
103 | 124 |
|
125 |
int add_function(int prescale_opt, void *rtc_func (void)) |
|
126 |
{ |
|
127 |
if(function_count+1>=MAX_FUNCTIONS) |
|
128 |
return -1; |
|
129 |
function_count++; |
|
130 |
_rtc_f[function_count] = rtc_func; |
|
131 |
_rtc_pulse[function_count] = 0; |
|
132 |
_rtc_scale[function_count] = prescale_opt; |
|
133 |
return 1; |
|
134 |
} |
|
135 |
|
|
136 |
int rtc_init(int prescale_opt, void *rtc_func(void)){ |
|
137 |
int temp[] = {prescale_opt}; |
|
138 |
void (*temp2[MAX_FUNCTIONS])(void) = {rtc_func}; |
|
139 |
return rtc_multi_init(temp, temp2, 1); |
|
140 |
} |
|
141 |
|
|
104 | 142 |
/** |
105 | 143 |
* Returns the time elapsed in seconds since the last call to |
106 | 144 |
* rtc_init or rtc_reset. |
... | ... | |
109 | 147 |
* |
110 | 148 |
* @see rtc_init, rtc_reset |
111 | 149 |
**/ |
150 |
/* |
|
112 | 151 |
int rtc_get(void){ |
113 | 152 |
return _rtc_val; |
114 |
} |
|
153 |
}*/
|
|
115 | 154 |
|
116 | 155 |
/** |
117 | 156 |
* Resets the real time clock counter to 0. |
118 | 157 |
* |
119 | 158 |
* @see rtc_init, rtc_get |
120 | 159 |
**/ |
160 |
/* |
|
121 | 161 |
void rtc_reset(void){ |
122 | 162 |
_rtc_val = 0; |
123 |
} |
|
163 |
}*/
|
|
124 | 164 |
|
125 | 165 |
/** @} **/ //end defgroup |
126 | 166 |
|
127 | 167 |
/* Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated. |
128 | 168 |
Bascially, since the pulse is hard set at 1/16s you want to count how many 16ths of a second have passed |
129 | 169 |
and when it reaches the amount of time you want, execute the code. */ |
170 |
|
|
130 | 171 |
SIGNAL(TIMER3_COMPA_vect) { |
131 |
|
|
132 |
if (_rtc_pulse == _rtc_scale) { |
|
133 |
//Increment the real time clock counter |
|
134 |
_rtc_val++; |
|
135 |
|
|
136 |
//Calls the function tied to the real time clock if defined |
|
137 |
if(_rtc_f != 0) |
|
138 |
_rtc_f(); |
|
139 |
|
|
140 |
//Resets the pulse until the next scale is matched |
|
141 |
_rtc_pulse = 0; |
|
142 |
} |
|
143 |
|
|
172 |
for(int functionNumber = 0; functionNumber < function_count; functionNumber++) |
|
173 |
{ |
|
174 |
if (_rtc_pulse[functionNumber] == _rtc_scale[functionNumber]) { |
|
175 |
//Increment the real time clock counter |
|
176 |
_rtc_val[functionNumber]++; |
|
177 |
|
|
178 |
//Calls the function tied to the real time clock if defined |
|
179 |
_rtc_f[functionNumber](); |
|
180 |
|
|
181 |
//Resets the pulse until the next scale is matched |
|
182 |
_rtc_pulse[functionNumber] = 0; |
|
183 |
} |
|
184 |
_rtc_pulse[functionNumber]++; |
|
185 |
} |
|
144 | 186 |
//Updates the amount of pulses seen since the last scale match |
145 |
_rtc_pulse++; |
|
146 | 187 |
|
147 | 188 |
} |
148 |
|
branches/encoders/code/projects/libdragonfly/time.h | ||
---|---|---|
11 | 11 |
#ifndef _TIME_H_ |
12 | 12 |
#define _TIME_H_ |
13 | 13 |
|
14 |
/*Maximum # of functions*/ |
|
15 |
#define MAX_FUNCTIONS 10 |
|
16 |
|
|
17 |
|
|
14 | 18 |
/* Predefined times for prescale_opt in time.c. |
15 | 19 |
To make you own, know that a pulse is 1/16th of a second. You cannot get less than this. To get more, you need |
16 | 20 |
to know how many 16ths of a second are in the time you want. (Time_desired * 16 = prescaler_opt) |
... | ... | |
37 | 41 |
/** @brief Delay execution for the specified time **/ |
38 | 42 |
void delay_ms(int ms) ; |
39 | 43 |
/** @brief Enable the realtime clock **/ |
40 |
void rtc_init(int prescale_opt, void (*rtc_func)(void));
|
|
44 |
int rtc_multi_init(int* prescale_opt, void (*rtc_fun[])(void), int argc);
|
|
41 | 45 |
/** @brief Reset the counter of the realtime clock **/ |
42 | 46 |
void rtc_reset(void); |
43 | 47 |
/** @brief Get the value of the realtime clock. **/ |
44 | 48 |
int rtc_get(void); |
45 | 49 |
|
50 |
int add_function(int prescale_opt, void *rtc_f (void)); |
|
51 |
|
|
52 |
int rtc_init(int prescale_opt, void *rtc_func(void)); |
|
53 |
|
|
46 | 54 |
/** @} **/ |
47 | 55 |
|
48 | 56 |
#endif |
Also available in: Unified diff