Project

General

Profile

Revision 336

Updated wireless to use a circular buffer instead of a queue using malloc. Tested on both the computer and robots with a token ring, and was successful.

View differences:

time.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 *
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file time.c
29
 * @brief Timer code
30
 *
31
 * Implementation of functions for timers.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
/*
37
time.c
38
anything that requires a delay
39
mostly delay_ms
40

  
41
author: Robotics Club, Colony Project
42

  
43
Change Log:
44
	2.5.07 - Kevin
45
		Aaron fixed the orb/servo code and made them use timer3 but compare registers B and C. He hard set the prescaler
46
		to 8 so the RTC broke. Changed it so that we use a 8 prescaler which sets the compare match at 1/16th of a second.
47
		You now count how many 16ths of a second you want until you trigger your actual interrupt. Works. Changed defines
48
		for time so you can still call rtc_init with a scale but now it is defined in terms of actual time like second, quarter_second
49
		etc. Read that section in the time.h file for more information. Tested and works, though the clock drifts more than
50
		it used to
51
	1.30.07 - Kevin
52
		Modified the clock to run on timer3 on the Dragonfly. Works with decent accuracy. Using a prescaler of 256
53
	the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of
54
	256 change it by that multiple. Refer to the time.h file for all possible prescalers.
55
		The interrupt will call a specified function _rtc_func every pulse.
56
		All of it has been tested and it works.
57

  
58
*/
59
#include <avr/interrupt.h>
60
#include <util/delay.h>
61
#include <time.h>
62
#include <serial.h>
63

  
64
static volatile int _rtc_val = 0;
65
static volatile int _rtc_pulse = 0;
66
static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
67
static void (*_rtc_f)(void) = 0;
68

  
69
/**
70
 * @defgroup time Time
71
 * @brief Time functions
72
 *
73
 * Functions dealing with time.
74
 *
75
 * @{
76
 **/
77

  
78
/**
79
 * Delays for the specified number of milliseconds.
80
 * The accuracy of this function is unknown.
81
 *
82
 * @param ms the number of milliseconds to delay for
83
 **/
84
void delay_ms(int ms)
85
{
86
	for(; ms > 15; ms-=15)
87
		_delay_ms(15);
88
	_delay_ms(ms);
89
}
90

  
91

  
92
/* 	Prescales defined in time.h. SECOND will give you 1 second.
93
	More scales are defined in the time.h file.
94
	rtc_func is the address to a function that you want called every clock tick. */
95
/**
96
 * Initializes the real time clock. Prescales are defined in time.h.
97
 * For example, SECOND will give 1 second. The specified function is
98
 * called every clock tick. For the real time clock to activate,
99
 * interrupts must be enabled. (through sei() )
100
 *
101
 * @param prescale_opt the period with which the timer is triggered
102
 * @param rtc_func the function called when the timer is triggered
103
 *
104
 * @see rtc_get, rtc_reset
105
 *
106
 **/
107
void rtc_init(int prescale_opt, void (*rtc_func)(void)) {
108

  
109
	//Clear timer register for Timer 3
110
	TCNT3 = 0;
111

  
112
	/* 	This sets the Waveform Generation Module to CTC (Clear Timer on Compare) Mode (100)
113
		See page135 in Atmega128 Docs for more modes and explanations */
114
	TCCR3B |= _BV(WGM32);
115

  
116
	/* 	This sets the prescaler for the system clock (8MHz) ie: divides the clock by some number.
117
		Currently set to a prescaler of 8 because that is what the orb and servos use (they are on this timer as well)
118
		See page137 in Atemga128 Docs for all the available prescalers */
119
	TCCR3B |= _BV(CS31);
120

  
121
	/* 	Sets the two regsiters that we compare against. So the timer counts up to this number and
122
		then resets back to 0 and calls the compare match interrupt.
123
		8x10^6 / 8 = 1/16 Second. All values are based off of this number. Do not change it unless you
124
		are l337*/
125

  
126
	OCR3A = 0xF424;
127

  
128
	/* 	Enable Output Compare A Interrupt. When OCR3A is met by the timer TCNT3 this interrupt will be
129
		triggerd. (See page140 in Atmega128 Docs for more information */
130
	ETIMSK |= _BV(OCIE3A);
131

  
132
	/*	Store the pointer to the function to be used in the interrupt */
133
	_rtc_f = rtc_func;
134

  
135
	/*	Store how many 1/16ths of a second you want to let by before triggering an interrupt */
136
	_rtc_scale = prescale_opt;
137
}
138

  
139
/**
140
 * Returns the time elapsed in seconds since the last call to
141
 * rtc_init or rtc_reset.
142
 *
143
 * @return the number of seconds since the last call to rtc_init or rtc_reset
144
 *
145
 * @see rtc_init, rtc_reset
146
 **/
147
int rtc_get(void){
148
	return _rtc_val;
149
}
150

  
151
/**
152
 * Resets the real time clock counter to 0.
153
 *
154
 * @see rtc_init, rtc_get
155
 **/
156
void rtc_reset(void){
157
	_rtc_val = 0;
158
}
159

  
160
/** @} **/ //end defgroup
161

  
162
/*	Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated.
163
	Bascially, since the pulse is hard set at 1/16s  you want to count how many 16ths of a second have passed
164
	and when it reaches the amount of time you want, execute the code. */
165
SIGNAL(TIMER3_COMPA_vect) {
166

  
167
	if (_rtc_pulse ==  _rtc_scale) {
168
		//Increment the real time clock counter
169
		_rtc_val++;
170

  
171
		//Calls the function tied to the real time clock if defined
172
		if(_rtc_f != 0)
173
			_rtc_f();
174

  
175
		//Resets the pulse until the next scale is matched
176
		_rtc_pulse = 0;
177
	}
178

  
179
	//Updates the amount of pulses seen since the last scale match
180
	_rtc_pulse++;
181

  
182
}
183

  
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file time.c
29
 * @brief Timer code
30
 *
31
 * Implementation of functions for timers.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
/*
37
time.c
38
anything that requires a delay
39
mostly delay_ms
40

  
41
author: Robotics Club, Colony Project
42

  
43
Change Log:
44
	2.5.07 - Kevin
45
		Aaron fixed the orb/servo code and made them use timer3 but compare registers B and C. He hard set the prescaler
46
		to 8 so the RTC broke. Changed it so that we use a 8 prescaler which sets the compare match at 1/16th of a second.
47
		You now count how many 16ths of a second you want until you trigger your actual interrupt. Works. Changed defines
48
		for time so you can still call rtc_init with a scale but now it is defined in terms of actual time like second, quarter_second
49
		etc. Read that section in the time.h file for more information. Tested and works, though the clock drifts more than
50
		it used to
51
	1.30.07 - Kevin
52
		Modified the clock to run on timer3 on the Dragonfly. Works with decent accuracy. Using a prescaler of 256
53
	the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of
54
	256 change it by that multiple. Refer to the time.h file for all possible prescalers.
55
		The interrupt will call a specified function _rtc_func every pulse.
56
		All of it has been tested and it works.
57

  
58
*/
59
#include <avr/interrupt.h>
60
#include <util/delay.h>
61
#include <time.h>
62
#include <serial.h>
63

  
64
static volatile int _rtc_val = 0;
65
static volatile int _rtc_pulse = 0;
66
static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
67
static void (*_rtc_f)(void) = 0;
68

  
69
/**
70
 * @defgroup time Time
71
 * @brief Time functions
72
 * 
73
 * Functions dealing with time.
74
 * 
75
 * @{
76
 **/
77

  
78
/**
79
 * Delays for the specified number of milliseconds.
80
 * The accuracy of this function is unknown.
81
 *
82
 * @param ms the number of milliseconds to delay for
83
 **/
84
void delay_ms(int ms) 
85
{
86
	for(; ms > 15; ms-=15)
87
		_delay_ms(15);
88
	_delay_ms(ms);
89
}
90

  
91

  
92
/* 	Prescales defined in time.h. SECOND will give you 1 second.
93
	More scales are defined in the time.h file.
94
	rtc_func is the address to a function that you want called every clock tick. */
95
/**
96
 * Initializes the real time clock. Prescales are defined in time.h.
97
 * For example, SECOND will give 1 second. The specified function is
98
 * called every clock tick. For the real time clock to activate,
99
 * interrupts must be enabled. (through sei() )
100
 *
101
 * @param prescale_opt the period with which the timer is triggered
102
 * @param rtc_func the function called when the timer is triggered
103
 *
104
 * @see rtc_get, rtc_reset
105
 *
106
 **/
107
void rtc_init(int prescale_opt, void (*rtc_func)(void)) {
108
	
109
	//Clear timer register for Timer 3
110
	TCNT3 = 0;
111
	
112
	/* 	This sets the Waveform Generation Module to CTC (Clear Timer on Compare) Mode (100)
113
		See page135 in Atmega128 Docs for more modes and explanations */
114
	TCCR3B |= _BV(WGM32);
115
	
116
	/* 	This sets the prescaler for the system clock (8MHz) ie: divides the clock by some number.
117
		Currently set to a prescaler of 8 because that is what the orb and servos use (they are on this timer as well)
118
		See page137 in Atemga128 Docs for all the available prescalers */
119
	TCCR3B |= _BV(CS31);
120
	
121
	/* 	Sets the two regsiters that we compare against. So the timer counts up to this number and
122
		then resets back to 0 and calls the compare match interrupt.
123
		8x10^6 / 8 = 1/16 Second. All values are based off of this number. Do not change it unless you
124
		are l337*/
125
		
126
	OCR3A = 0xF424;	
127

  
128
	/* 	Enable Output Compare A Interrupt. When OCR3A is met by the timer TCNT3 this interrupt will be
129
		triggerd. (See page140 in Atmega128 Docs for more information */
130
	ETIMSK |= _BV(OCIE3A);
131
	
132
	/*	Store the pointer to the function to be used in the interrupt */
133
	_rtc_f = rtc_func;
134
	
135
	/*	Store how many 1/16ths of a second you want to let by before triggering an interrupt */
136
	_rtc_scale = prescale_opt;
137
}
138

  
139
/**
140
 * Returns the time elapsed in seconds since the last call to
141
 * rtc_init or rtc_reset.
142
 *
143
 * @return the number of seconds since the last call to rtc_init or rtc_reset
144
 *
145
 * @see rtc_init, rtc_reset
146
 **/
147
int rtc_get(void){
148
	return _rtc_val;
149
}
150

  
151
/**
152
 * Resets the real time clock counter to 0.
153
 *
154
 * @see rtc_init, rtc_get
155
 **/
156
void rtc_reset(void){
157
	_rtc_val = 0;
158
}
159

  
160
/** @} **/ //end defgroup
161

  
162
/*	Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated.
163
	Bascially, since the pulse is hard set at 1/16s  you want to count how many 16ths of a second have passed
164
	and when it reaches the amount of time you want, execute the code. */
165
SIGNAL(TIMER3_COMPA_vect) {
166

  
167
	if (_rtc_pulse ==  _rtc_scale) {
168
		//Increment the real time clock counter
169
		_rtc_val++;
170
		
171
		//Calls the function tied to the real time clock if defined
172
		if(_rtc_f != 0)
173
			_rtc_f();
174
		
175
		//Resets the pulse until the next scale is matched
176
		_rtc_pulse = 0;
177
	}	
178
	
179
	//Updates the amount of pulses seen since the last scale match
180
	_rtc_pulse++;
181
	
182
}
183

  

Also available in: Unified diff