Index: time.c
===================================================================
--- time.c	(revision 1460)
+++ time.c	(revision 1461)
@@ -1,66 +1,66 @@
-/**
- * Copyright (c) 2007 Colony Project
- * 
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- * 
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- **/
-
-
-/**
- * @file time.c
- * @brief Timer code
- *
- * Implementation of functions for timers.
- *
- * @author Colony Project, CMU Robotics Club
- **/
-
-/*
-  time.c
-  anything that requires a delay
-  mostly delay_ms
-
-  author: Robotics Club, Colony Project
-
-  Change Log:
-  2.5.07 - Kevin
-  Aaron fixed the orb/servo code and made them use timer3 but compare registers B and C. He hard set the prescaler
-  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.
-  You now count how many 16ths of a second you want until you trigger your actual interrupt. Works. Changed defines
-  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
-  etc. Read that section in the time.h file for more information. Tested and works, though the clock drifts more than
-  it used to
-  1.30.07 - Kevin
-  Modified the clock to run on timer3 on the Dragonfly. Works with decent accuracy. Using a prescaler of 256
-  the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of
-  256 change it by that multiple. Refer to the time.h file for all possible prescalers.
-  The interrupt will call a specified function _rtc_func every pulse.
-  All of it has been tested and it works.
-
-*/
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include "time.h"
-
+/**
+ * Copyright (c) 2007 Colony Project
+ * 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ **/
 
+
+/**
+ * @file time.c
+ * @brief Timer code
+ *
+ * Implementation of functions for timers.
+ *
+ * @author Colony Project, CMU Robotics Club
+ **/
+
+/*
+  time.c
+  anything that requires a delay
+  mostly delay_ms
+
+  author: Robotics Club, Colony Project
+
+  Change Log:
+  2.5.07 - Kevin
+  Aaron fixed the orb/servo code and made them use timer3 but compare registers B and C. He hard set the prescaler
+  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.
+  You now count how many 16ths of a second you want until you trigger your actual interrupt. Works. Changed defines
+  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
+  etc. Read that section in the time.h file for more information. Tested and works, though the clock drifts more than
+  it used to
+  1.30.07 - Kevin
+  Modified the clock to run on timer3 on the Dragonfly. Works with decent accuracy. Using a prescaler of 256
+  the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of
+  256 change it by that multiple. Refer to the time.h file for all possible prescalers.
+  The interrupt will call a specified function _rtc_func every pulse.
+  All of it has been tested and it works.
+
+*/
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "time.h"
+
+
 /* Calculate how many cycles to delay for to get 1 ms. Based on F_CPU which should be defined by the makefile */
 #ifdef F_CPU
 #define WAIT_CYCLES ((F_CPU / 1000) / 10)
@@ -67,25 +67,28 @@
 #else
 #define WAIT_CYCLES (8000 / 10)
 #endif
-
-static volatile int _rtc_val = 0;
-static volatile int _rtc_pulse = 0;
-static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
-static void (*_rtc_f)(void) = 0;
 
 
-
-/**
- * @defgroup time Time
- * @brief Time functions
- * 
- * Functions dealing with time.
- * 
- * @{
- **/
-
-/**
- * Delays for the specified number of milliseconds.
+unsigned char time_initd = 0;
+
+static volatile int _rtc_val = 0;
+static volatile int _rtc_pulse = 0;
+static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
+static void (*_rtc_f)(void) = 0;
+
+
+
+/**
+ * @defgroup time Time
+ * @brief Time functions
+ * 
+ * Functions dealing with time.
+ * 
+ * @{
+ **/
+
+/**
+ * Delays for the specified number of milliseconds.
  * It depends on F_CPU to be defined in order to calculate how many cycles
  * it should delay. If it is not defined, a default clock of 8MHz is assumed.
  * 
@@ -92,15 +95,15 @@
  * We use _delay_loop_2 which will run assembly instructions that should be
  * 4 cycles long. Optimizations must be enabled for this to be true.
  * That function is called to ensure around 1ms per execution. To generate
- * multiple ms we run a for loop of how many milliseconds are desired.
+ * multiple ms we run a for loop of how many milliseconds are desired.
  *
  * The error should be just the skew on the oscillator as the formula to 
  * calculate delay cycles should always be a whole number. The is some skew
  * in practice though it is unavoidable. Delaying for less than 1s should make
  * the error negligable.
- *
- * @param ms the number of milliseconds to delay for
- **/
+ *
+ * @param ms the number of milliseconds to delay for
+ **/
 void delay_ms(int ms) {
     for (; ms > 0; ms--) {
         _delay_loop_2(WAIT_CYCLES);
@@ -107,95 +110,105 @@
     }
 }
 
-
-/* 	Prescales defined in time.h. SECOND will give you 1 second.
-	More scales are defined in the time.h file.
-	rtc_func is the address to a function that you want called every clock tick. */
-/**
- * Initializes the real time clock. Prescales are defined in time.h.
- * For example, SECOND will give 1 second. The specified function is
- * called every clock tick. For the real time clock to activate,
- * interrupts must be enabled. (through sei() )
- *
- * @param prescale_opt the period with which the timer is triggered
- * @param rtc_func the function called when the timer is triggered
- *
- * @see rtc_get, rtc_reset
- *
- **/
-void rtc_init(int prescale_opt, void (*rtc_func)(void)) {
-	
-  //Clear timer register for Timer 3
-  TCNT3 = 0;
-	
-  /* 	This sets the Waveform Generation Module to CTC (Clear Timer on Compare) Mode (100)
-	See page135 in Atmega128 Docs for more modes and explanations */
-  TCCR3B |= _BV(WGM32);
-	
-  /* 	This sets the prescaler for the system clock (8MHz) ie: divides the clock by some number.
-	Currently set to a prescaler of 8 because that is what the orb and servos use (they are on this timer as well)
-	See page137 in Atemga128 Docs for all the available prescalers */
-  TCCR3B |= _BV(CS31);
-	
-  /* 	Sets the two regsiters that we compare against. So the timer counts up to this number and
-	then resets back to 0 and calls the compare match interrupt.
-	8x10^6 / 8 = 1/16 Second. All values are based off of this number. Do not change it unless you
-	are l337*/
-		
-  OCR3A = 0xF424;	
-
-  /* 	Enable Output Compare A Interrupt. When OCR3A is met by the timer TCNT3 this interrupt will be
-	triggerd. (See page140 in Atmega128 Docs for more information */
-  ETIMSK |= _BV(OCIE3A);
-	
-  /*	Store the pointer to the function to be used in the interrupt */
-  _rtc_f = rtc_func;
-	
-  /*	Store how many 1/16ths of a second you want to let by before triggering an interrupt */
-  _rtc_scale = prescale_opt;
-}
-
-/**
- * Returns the time elapsed in seconds since the last call to
- * rtc_init or rtc_reset.
- *
- * @return the number of seconds since the last call to rtc_init or rtc_reset
- *
- * @see rtc_init, rtc_reset
- **/
-int rtc_get(void) {
-  return _rtc_val;
-}
-
-/**
- * Resets the real time clock counter to 0.
- *
- * @see rtc_init, rtc_get
- **/
-void rtc_reset(void) {
-  _rtc_val = 0;
-}
-
-/** @} **/ //end defgroup
-
-/*	Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated.
-	Bascially, since the pulse is hard set at 1/16s  you want to count how many 16ths of a second have passed
-	and when it reaches the amount of time you want, execute the code. */
-SIGNAL(TIMER3_COMPA_vect) {
-
-  if (_rtc_pulse ==  _rtc_scale) {
-    //Increment the real time clock counter
-    _rtc_val++;
-		
-    //Calls the function tied to the real time clock if defined
-    if(_rtc_f != 0)
-      _rtc_f();
-		
-    //Resets the pulse until the next scale is matched
-    _rtc_pulse = 0;
-  }	
-	
-  //Updates the amount of pulses seen since the last scale match
-  _rtc_pulse++;
-	
-}
+
+/* 	Prescales defined in time.h. SECOND will give you 1 second.
+	More scales are defined in the time.h file.
+	rtc_func is the address to a function that you want called every clock tick. */
+/**
+ * Initializes the real time clock. Prescales are defined in time.h.
+ * For example, SECOND will give 1 second. The specified function is
+ * called every clock tick. For the real time clock to activate,
+ * interrupts must be enabled. (through sei() )
+ *
+ * @param prescale_opt the period with which the timer is triggered
+ * @param rtc_func the function called when the timer is triggered
+ *
+ * @return 0 if init succesfull, an error code otherwise
+ *
+ * @see rtc_get, rtc_reset
+ *
+ **/
+int rtc_init(int prescale_opt, void (*rtc_func)(void)) {
+
+  if(time_initd) {
+    return ERROR_INIT_ALREADY_INITD;
+  }
+	
+  //Clear timer register for Timer 3
+  TCNT3 = 0;
+	
+  /* 	This sets the Waveform Generation Module to CTC (Clear Timer on Compare) Mode (100)
+	See page135 in Atmega128 Docs for more modes and explanations */
+  TCCR3B |= _BV(WGM32);
+	
+  /* 	This sets the prescaler for the system clock (8MHz) ie: divides the clock by some number.
+	Currently set to a prescaler of 8 because that is what the orb and servos use (they are on this timer as well)
+	See page137 in Atemga128 Docs for all the available prescalers */
+  TCCR3B |= _BV(CS31);
+	
+  /* 	Sets the two regsiters that we compare against. So the timer counts up to this number and
+	then resets back to 0 and calls the compare match interrupt.
+	8x10^6 / 8 = 1/16 Second. All values are based off of this number. Do not change it unless you
+	are l337*/
+		
+  OCR3A = 0xF424;	
+
+  /* 	Enable Output Compare A Interrupt. When OCR3A is met by the timer TCNT3 this interrupt will be
+	triggerd. (See page140 in Atmega128 Docs for more information */
+  ETIMSK |= _BV(OCIE3A);
+	
+  /*	Store the pointer to the function to be used in the interrupt */
+  _rtc_f = rtc_func;
+	
+  /*	Store how many 1/16ths of a second you want to let by before triggering an interrupt */
+  _rtc_scale = prescale_opt;
+
+  time_initd = 1;
+
+  return 0;
+}
+
+/**
+ * Returns the time elapsed in seconds since the last call to
+ * rtc_init or rtc_reset.
+ *
+ * @return the number of seconds since the last call to rtc_init or rtc_reset
+ *
+ * @see rtc_init, rtc_reset
+ **/
+int rtc_get(void) {
+  return _rtc_val;
+}
+
+/**
+ * Resets the real time clock counter to 0.
+ *
+ * @see rtc_init, rtc_get
+ **/
+void rtc_reset(void) {
+  _rtc_val = 0;
+}
+
+/** @} **/ //end defgroup
+
+/*	Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated.
+	Bascially, since the pulse is hard set at 1/16s  you want to count how many 16ths of a second have passed
+	and when it reaches the amount of time you want, execute the code. */
+SIGNAL(TIMER3_COMPA_vect) {
+
+  if (_rtc_pulse ==  _rtc_scale) {
+    //Increment the real time clock counter
+    _rtc_val++;
+		
+    //Calls the function tied to the real time clock if defined
+    if(_rtc_f != 0)
+      _rtc_f();
+		
+    //Resets the pulse until the next scale is matched
+    _rtc_pulse = 0;
+  }	
+	
+  //Updates the amount of pulses seen since the last scale match
+  _rtc_pulse++;
+	
+}
