Project

General

Profile

Revision 1461

Added by Brad Neuman over 13 years ago

updated all the library code to have sensible _init behavior.
Almost all of the library components have a global variable which gets set after init and the functions inside will fail with an error code if init has not been called. Also, the init functions themselves check this variable and will bail out without doing any damage if that init has already been called

View differences:

trunk/code/lib/include/libdragonfly/spi.h
12 12
#ifndef __SPI_H__
13 13
#define __SPI_H__
14 14

  
15
#include<dragonfly_lib.h>
16

  
15 17
#define DOUBLE_SCK 1
16 18
#define SPR0_BIT 1
17 19

  
......
32 34
* @param spi_fun_recv_t The function that handles SPI data, byte for byte.
33 35
* @param spi_fun_recv_complete_t  Called on a completed transmission - typically for cleaning up.
34 36
*/
35
void spi_init (spi_fun_recv_t, spi_fun_recv_complete_t);
37
int spi_init (spi_fun_recv_t, spi_fun_recv_complete_t);
36 38

  
37 39
/** 
38 40
* @brief Initialize SPI transfer.
39 41
* 
40 42
* @param char The number of bytes to transfer.
41 43
*/
42
void spi_transfer (char);
44
int spi_transfer (char);
43 45

  
44 46
/**@}**/ //end group
45 47

  
trunk/code/lib/include/libdragonfly/time.h
37 37
#ifndef _TIME_H_
38 38
#define _TIME_H_
39 39

  
40
#include <dragonfly_lib.h>
41

  
40 42
/*	Predefined times for prescale_opt in time.c.
41 43
	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
42 44
	to know how many 16ths of a second are in the time you want. (Time_desired * 16 = prescaler_opt)
......
63 65
/** @brief Delay execution for the specified time **/
64 66
void delay_ms(int ms) ;
65 67
/** @brief Enable the realtime clock **/
66
void rtc_init(int prescale_opt, void (*rtc_func)(void));
68
int rtc_init(int prescale_opt, void (*rtc_func)(void));
67 69
/** @brief Reset the counter of the realtime clock **/
68 70
void rtc_reset(void);
69 71
/** @brief Get the value of the realtime clock. **/
trunk/code/lib/include/libdragonfly/motor.h
38 38
#ifndef _MOTOR_H
39 39
#define _MOTOR_H
40 40

  
41
#include <dragonfly_lib.h>
41 42
#include <avr/io.h>
42 43
/**
43 44
 * @addtogroup motors
......
50 51
#define BACKWARD 0
51 52

  
52 53
/** @brief Initialize the motors **/
53
void motors_init(void);
54
int motors_init(void);
54 55
/** @brief Set speed and direction of motor1 
55 56
 *  @deprecated use the left motor function instead. it's more intuitive and easier to read.**/
56
void motor1_set(int direction, int speed);
57
int motor1_set(int direction, int speed);
57 58
/** @brief Set speed and direction of motor2 
58 59
 *  @deprecated use the right motor function instead. it's more intuitive and easier to read.**/
59
void motor2_set(int direction, int speed);
60
int motor2_set(int direction, int speed);
60 61
/** @brief Set speed and direction of left motor **/
61
void motor_l_set(int direction, int speed);
62
int motor_l_set(int direction, int speed);
62 63
/** @brief Set speed and direction of right motor **/
63
void motor_r_set(int direction, int speed);
64
int motor_r_set(int direction, int speed);
64 65
/** @brief Turn the motors off **/
65
void motors_off(void);
66
int motors_off(void);
66 67

  
67 68
/**@}**/ // end addtogroup
68 69

  
trunk/code/lib/include/libdragonfly/analog.h
113 113

  
114 114
/** @brief Initialize analog ports. Will start running a loop
115 115
    if start_conversion is ADC_START.**/
116
void analog_init(int start_conversion);
116
int analog_init(int start_conversion);
117 117
/** @brief starts the analog loop. Doesn't do anything if the loop is already running. **/
118
void analog_start_loop(void);
118
int analog_start_loop(void);
119 119
/** @brief Stops the analog loop. Doesn't do anything if the loop is already stopped. **/
120
void analog_stop_loop(void);
120
int analog_stop_loop(void);
121 121
/** @brief Returns the status of the analog loop. **/
122 122
int analog_loop_status(void);
123 123
/** @brief Returns an 8-bit analog value from the look up table. Use this instead of analog_get8. **/
trunk/code/lib/include/libdragonfly/encoders.h
51 51
#define MagINCn _BV(1)
52 52
#define MagDECn _BV(0)
53 53

  
54
#ifdef BUFFER_SIZE
55
#error BUFFER_SIZE already defined!
56
#endif
57

  
54 58
/** @brief Buffer size **/
55 59
#define BUFFER_SIZE 46
56 60

  
57 61
#define ERR_VEL 1024
58 62

  
59 63
/** @brief Initialize encoders. **/
60
void encoders_init(void);
64
int encoders_init(void);
61 65
/** @brief Read instantaneous encoder value. **/
62 66
int encoder_read(char encoder);
63 67

  
......
72 76
/** @brief Get total distance traveled. **/
73 77
int encoder_get_dx(char encoder);
74 78
/** @brief Reset distance counter. **/
75
void encoder_rst_dx(char encoder);
79
int encoder_rst_dx(char encoder);
76 80
/** @brief Get time count: The number of encoder reads that have occurred. **/
77 81
int encoder_get_tc(void);
78 82
/** @brief Reset the time count. **/
79
void encoder_rst_tc(void);
83
int encoder_rst_tc(void);
80 84

  
81 85
/** @brief Waits for the next n encoder reading, then returns. **/
82
void encoder_wait( int nReadings );
86
int encoder_wait( int nReadings );
83 87

  
84 88
/**@}**/ //end group
85 89

  
trunk/code/lib/include/libdragonfly/dragonfly_lib.h
41 41
 * @{
42 42
 **/
43 43

  
44
//return value definitions
45
#define ERROR_INIT_FAILED 1
46
#define ERROR_INIT_ALREADY_INITD 2
47

  
48
#define ERROR_LIBRARY_NOT_INITD 3
49

  
44 50
// Configuration definitions
45 51
/** @brief Initialize analog **/
46 52
#define ANALOG 0x01
trunk/code/lib/include/libdragonfly/bom.h
57 57

  
58 58

  
59 59
/** @brief Initialize the bom according to bom type **/
60
void bom_init(char type);
60
int bom_init(char type);
61 61

  
62 62
/** @brief Refresh bom_val[] with new values from analog8.  analog_init and bom_init must be called for this to work. **/
63
void bom_refresh(int bit_field);
63
int bom_refresh(int bit_field);
64 64

  
65 65
/** @brief Gets the bom reading from bom_val[which].  Call bom_refresh beforehand to read new bom values. **/
66 66
int bom_get(int which);
......
72 72
int bom_get_max10(int *dist);
73 73

  
74 74
/** @brief Enables the selected bom leds on a BOM1.5 **/
75
void bom_set_leds(int bit_field);
75
int bom_set_leds(int bit_field);
76 76

  
77 77
/** @brief (DEPRECATED) Gets and compares all bom values.  Returns the index to the highest value element since last refresh. **/
78 78
int get_max_bom(void);
79 79

  
80 80
/** @brief Turns on all BOM leds, or turns on enabled leds on a BOM1.5. **/
81
void bom_on(void);
81
int bom_on(void);
82 82

  
83 83
/** @brief Turns off all bom leds. **/
84
void bom_off(void);
84
int bom_off(void);
85 85

  
86 86
/** @} **/
87 87

  
trunk/code/lib/include/libdragonfly/serial.h
68 68
#ifndef _SERIAL_H
69 69
#define _SERIAL_H
70 70

  
71
#include <dragonfly_lib.h>
71 72
#include <inttypes.h>
72 73
#include <avr/pgmspace.h>
73 74

  
......
87 88
#endif
88 89

  
89 90
/** @brief Initialize the USB **/
90
void usb_init(void);
91
int usb_init(void);
91 92
/** @brief Print a character to USB **/
92 93
int usb_putc(char c);
93 94
/** @brief Read a character from USB **/
......
97 98
/** @brief Print a string to USB **/
98 99
int usb_puts(char *s);
99 100
/** @brief Print a string from program space to USB **/
100
void usb_puts_P (PGM_P s);
101
int usb_puts_P (PGM_P s);
101 102
/** @brief Print an integer to USB **/
102 103
int usb_puti(int value);
103 104
/** @brief Determine a hexadecimal digit **/
104 105
uint8_t hex_digit (uint8_t value);
105 106
/** @brief Print a fixed width hexadecimal representation to USB **/
106
void usb_puth16 (uint16_t value);
107
int usb_puth16 (uint16_t value);
107 108
/** @brief Print a fixed width hexadecimal representation to USB **/
108
void usb_puth8(uint8_t value);
109
int usb_puth8(uint8_t value);
109 110
/** @brief Alias for usb_puth16 **/
110 111
static inline void usb_puth (uint16_t value) { usb_puth16 (value); };
111 112

  
......
130 131
#endif
131 132

  
132 133
/** @brief Initialize the XBee **/
133
void xbee_init(void);
134
int xbee_init(void);
134 135
/** @brief Print a character to the XBee **/
135 136
int xbee_putc(char c);
136 137
/** @brief Read a character from the XBee **/
trunk/code/lib/include/libdragonfly/rangefinder.h
37 37
#ifndef _RANGEFINDER_H_
38 38
#define _RANGEFINDER_H_
39 39

  
40
#include <dragonfly_lib.h>
41

  
40 42
/**
41 43
 * @addtogroup rangefinder
42 44
 * @{
......
58 60
#define MAX_IR_ADC8 133
59 61

  
60 62
/** @brief Initialize the rangefinders **/
61
void range_init(void);
63
int range_init(void);
62 64
/** @brief Read the distance from a rangefinder **/
63 65
int range_read_distance(int range_id);
64 66
/** @brief Convert logarithmic-scale distance readings to a linear scale **/
trunk/code/lib/include/libdragonfly/eeprom.h
1
/**
2
 * @file eeprom.h
3
 * @brief handles eeprom storage for persistent data
4
 *
5
 * Contains functions and definitions for reading and writing to eeprom
6
 *
7
 * @author Colony Project, Brad Neuman
8
 */
9
 
10 1
 #ifndef _EEPROM_H_
11 2
 #define _EEPROM_H_
12 3
 
13 4
 #define EEPROM_ROBOT_ID_ADDR 0x10
14 5
 #define EEPROM_BOM_TYPE_ADDR 0x14
15 6
 
16
 /** @brief store a byte to eeproem
17
  *  @return 0 if success, nonzero on failure
18
  */
19 7
 int eeprom_put_byte(unsigned int addr, unsigned char byte);
20 8
 
21
 /** @brief reads a byte from eeprom
22
  *
23
  *  Pass it thge address and a pointer to a byte where the byte at the
24
  *  address will be stored
25
  *
26
  *  @return 0 if successful (byte is set to the eeprom value at addr), 
27
  *  nonzero if there was a problem
28
   */
29 9
 int eeprom_get_byte(unsigned int addr, unsigned char *byte);
30 10
 
31
 /** @brief get stored robot ID
32
  *
33
  *  checks that EEPROM has been programed with an ID and returns it
34
  *
35
  *  @return the robot id, if it is stored. If it returns 0xFF it is probably invalid
36
  */
37 11
 unsigned char get_robotid(void);
38 12
  
39
   /** @brief get stored robot ID
40
  *
41
  * checks that EEPROM has been programed with an BOM type and returns it
42
  *
43
  *  @return the robot bom type as defined in bom.h, if it is stored. If it returns 0xFF it is probably invalid
44
  */
45 13
 unsigned char get_bom_type(void);
46 14
 
47 15
 #endif
trunk/code/projects/test/test_motors.c
61 61
    delay_ms(3000);
62 62
	//while(1){;}
63 63

  
64

  
65
    motors_off();
66

  
64 67
    return 0;
65 68
}
66 69

  
......
69 72
left >154 forward
70 73
right >150 forward
71 74
both >152 backward
72
*/
75
*/
trunk/code/projects/test/test_rangefinder.c
30 30
    int i;  // index
31 31
    int sensor[5] = {IR4, IR3, IR2, IR1, IR5};
32 32
    int color[5] = {RED, ORANGE, YELLOW, GREEN, BLUE};
33
    int ret;
33 34

  
34 35
    // flash orbs BLUE 3 times
35 36
    for (i = 0; i < 3; i++) {
......
44 45
	orb2_set_color(color[i]);
45 46

  
46 47
	// wait for sensor interaction
47
	while (range_read_distance(sensor[i]) == -1)
48
	while ((ret = range_read_distance(sensor[i])) == -1) {
48 49
	    // stay RED until IR4 sees something
49 50
	    orb1_set_color(RED);
51
	    if(ret == -3) { //library not init'd 
52
	      while(1) {
53
		orb2_set_color(GREEN);
54
		orb1_set_color(RED);
55
		delay_ms(250);
56
		orb1_set_color(GREEN);
57
		orb2_set_color(RED);
58
		delay_ms(250);
59
	      }
60
	    }
61
	}
50 62

  
51 63
	orb1_set_color(GREEN);
52 64
	delay_ms(TEST_TIME);
trunk/code/projects/test/main.c
3 3
#define RUN_TEST(f) extern int f(void); f();
4 4

  
5 5
int main(void) {
6
  RUN_TEST(testinits);
7

  
6 8
  dragonfly_init(ALL_ON);
7 9

  
8 10
  while (1) {
9
    // RUN_TEST(testusb);
11
    //RUN_TEST(testusb);
10 12
    // RUN_TEST(testanalog);
11
    // RUN_TEST(testeeprom);
13
    //RUN_TEST(testeeprom);
12 14
    // RUN_TEST(testencoders);
13 15
    // RUN_TEST(testlcd);
14
    // RUN_TEST(testlights);
15
    // RUN_TEST(testmotors);
16
    // RUN_TEST(testrangefinder);
16
    //RUN_TEST(testlights);
17
    //RUN_TEST(testmotors);
18
    RUN_TEST(testrangefinder);
17 19
    // RUN_TEST(testtokenring);
18 20
    // RUN_TEST(testwireless);
19
    RUN_TEST(testxbee);
21
    //RUN_TEST(testxbee);
20 22
    delay_ms(1000);
21 23
  }
22 24

  
trunk/code/projects/hunter_prey/testbench/main.c
62 62
    delay8.tv_sec = 2;
63 63
    delay8.tv_nsec = 800000000;
64 64

  
65
    wl_set_com_port("/dev/ttyUSB0");
65
    wl_set_com_port("/dev/ttyUSB1");
66 66
    // set up wireless
67 67
    wl_basic_init_default();
68 68
    wl_set_channel(channel);
trunk/code/projects/libdragonfly/motor.c
43 43
 * @{
44 44
 **/
45 45

  
46
unsigned char motors_initd=0;
47

  
46 48
/**
47 49
 * Initializes both motors so that they can be used with future
48 50
 * calls to motor1_set and motor2_set.
49 51
 *
52
 * @return 0 if init succesfull, an error code otherwise
53
 *
50 54
 * @see motors_off, motor1_set, motor2_set
51 55
 **/
52
void motors_init( void ) {
56
int motors_init( void ) {
57

  
58
  if(motors_initd)
59
    return ERROR_INIT_ALREADY_INITD;
60

  
61

  
53 62
  // Configure counter such that we use phase correct
54 63
  // PWM with 8-bit resolution
55 64
  PORTA &= 0x0F;
......
65 74
  OCR1AL=0;
66 75
  OCR1BH=0;
67 76
  OCR1BL=0;
77

  
78
  motors_initd=1;
79
  return 0;
68 80
}
69 81

  
70 82
/**
......
74 86
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
75 87
 * @param speed The speed the motor will run at, in the range 0-255.
76 88
 * 
89
 * @return 0 if init succesfull, an error code otherwise
90
 *
77 91
 * @see motor_r_set, motors_init
78 92
 **/
79
void motor_l_set(int direction, int speed) {
93
int motor_l_set(int direction, int speed) {
94
  if(!motors_initd)
95
    return ERROR_LIBRARY_NOT_INITD;
80 96

  
81 97
  if(direction == 0) {
82 98
    // turn off PWM first if switching directions
......
98 114
	
99 115
  // Set the timer to count up to speed, an 8-bit value
100 116
  OCR1AL = speed;
117

  
118
  return 0;
101 119
}
102 120

  
103 121
/**
......
107 125
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
108 126
 * @param speed The speed the motor will run at, in the range 0-255.
109 127
 *
128
 * @return 0 if init succesfull, an error code otherwise
129
 *
110 130
 * @see motor_l_set, motors_init
111 131
 **/
112
void motor_r_set(int direction, int speed) {
132
int motor_r_set(int direction, int speed) {
133
  if(!motors_initd)
134
    return ERROR_LIBRARY_NOT_INITD;
135

  
113 136
  if(direction == 0) {
114 137
    //		PORTD |= 0x20;
115 138
    //		PORTD &= 0x7F;
......
131 154
    PORTA = (PORTA & 0x3F) | 0x40;
132 155
  }
133 156
  OCR1BL = speed;
157

  
158
  return 0;
134 159
}
135 160

  
136 161
/**
......
140 165
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
141 166
 * @param speed The speed the motor will run at, in the range 0-255.
142 167
 *
168
 * @return 0 if init succesfull, an error code otherwise
169
 *
143 170
 * @see motor2_set, motors_init
144 171
 **/
145
void motor1_set(int direction, int speed) {
146
	motor_l_set(direction, speed);
172
int motor1_set(int direction, int speed) {
173
  return motor_l_set(direction, speed);
147 174
}
148 175

  
149 176
/**
......
153 180
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
154 181
 * @param speed The speed the motor will run at, in the range 0-255.
155 182
 *
183
 * @return 0 if init succesfull, an error code otherwise
184
 *
156 185
 * @see motor2_set, motors_init
157 186
 **/
158
void motor2_set(int direction, int speed) {
159
	motor_r_set(direction, speed);
187
int motor2_set(int direction, int speed) {
188
  return motor_r_set(direction, speed);
160 189
}
161 190

  
162 191

  
163 192
/**
164 193
 * Turns off both motors.
165 194
 *
195
 * @return 0 if init succesfull, an error code otherwise
196
 *
166 197
 * @see motors_init
167 198
 **/
168
void motors_off( void ) {
199
int motors_off( void ) {
200
  if(!motors_initd)
201
    return ERROR_LIBRARY_NOT_INITD;
202

  
169 203
  OCR1AL = 0x0;
170 204
  OCR1BL = 0x0;
205

  
206
  return 0;
171 207
}
172 208

  
173 209
/**@}**///end defgroup
trunk/code/projects/libdragonfly/motor.h
38 38
#ifndef _MOTOR_H
39 39
#define _MOTOR_H
40 40

  
41
#include <dragonfly_lib.h>
41 42
#include <avr/io.h>
42 43
/**
43 44
 * @addtogroup motors
......
50 51
#define BACKWARD 0
51 52

  
52 53
/** @brief Initialize the motors **/
53
void motors_init(void);
54
int motors_init(void);
54 55
/** @brief Set speed and direction of motor1 
55 56
 *  @deprecated use the left motor function instead. it's more intuitive and easier to read.**/
56
void motor1_set(int direction, int speed);
57
int motor1_set(int direction, int speed);
57 58
/** @brief Set speed and direction of motor2 
58 59
 *  @deprecated use the right motor function instead. it's more intuitive and easier to read.**/
59
void motor2_set(int direction, int speed);
60
int motor2_set(int direction, int speed);
60 61
/** @brief Set speed and direction of left motor **/
61
void motor_l_set(int direction, int speed);
62
int motor_l_set(int direction, int speed);
62 63
/** @brief Set speed and direction of right motor **/
63
void motor_r_set(int direction, int speed);
64
int motor_r_set(int direction, int speed);
64 65
/** @brief Turn the motors off **/
65
void motors_off(void);
66
int motors_off(void);
66 67

  
67 68
/**@}**/ // end addtogroup
68 69

  
trunk/code/projects/libdragonfly/i2c.c
43 43
#include "i2c.h"
44 44
#include "ring_buffer.h"
45 45

  
46
//NOTE: this is here just to provide colony error codes, it can be safely removed
47
// for use in another project
48
#include <dragonfly_lib.h>
49

  
46 50
/**
47 51
 * @defgroup i2c I2C 
48 52
 *
......
78 82
 */
79 83
#define I2C_BIT_RATE_DIVIDER 0x0C
80 84

  
85
unsigned char i2c_initd=0;
86

  
81 87
static int start_flag;
82 88

  
83 89
static fun_mrecv_t master_recv_function;
......
105 111
 * @return 0 for success, nonzero for failure
106 112
 **/
107 113
int i2c_init(char addr, fun_mrecv_t master_recv, fun_srecv_t slave_recv, fun_send_t slave_send) {
114

  
115
    if(i2c_initd)
116
      return ERROR_INIT_ALREADY_INITD;
117

  
118

  
108 119
    master_recv_function = master_recv;
109 120
    slave_recv_function = slave_recv;
110 121
    slave_send_function = slave_send;
......
122 133
     * global messages to be accepted */
123 134
    TWAR = (addr << 1) | 1;
124 135
  
136
    i2c_initd = 1;
125 137
    return 0;
126 138
}
127 139

  
......
141 153
int i2c_send(char dest, char *data, unsigned int bytes) {
142 154
    int i;
143 155

  
156
    if(!i2c_initd)
157
      return ERROR_LIBRARY_NOT_INITD;
158

  
159

  
144 160
    /* adding data to be sent to ring buffers is not atomic,
145 161
     * so disable interrupts */
146 162
    cli();
......
180 196
 * @return 0 for success, nonzero for failure
181 197
 **/ 
182 198
int i2c_request(char dest) {
199
    if(!i2c_initd)
200
      return ERROR_LIBRARY_NOT_INITD;
201

  
183 202
    if(RING_BUFFER_FULL(i2c_write_buff))
184 203
        return -1;
185 204
  
trunk/code/projects/libdragonfly/serial.c
36 36
#include <avr/io.h>
37 37
#include "serial.h"
38 38

  
39
unsigned char usb_initd=0;
40
unsigned char xbee_initd=0;
41

  
39 42
#ifdef USE_STDIO
40 43

  
41 44
#include <stdio.h>
......
57 60
 * This must be called before any other usb function
58 61
 * may be used.
59 62
 **/
60
void usb_init() {
63
int usb_init() {
61 64
  //Set baud rate
62 65
  // - 115200 (both wired and wireless) is UBRR=8, U2X=1
63 66
  // - 9600 is U2X =1, UBRR = 107.
67

  
68
  if(usb_initd) {
69
    return ERROR_INIT_ALREADY_INITD;
70
  }
71

  
64 72
#if (USB_BAUD == 115200)
65 73
  UBRR0H = 0x00;
66 74
  UBRR0L = 8;
......
70 78
  UBRR0L = 103;
71 79
  UCSR0A |= _BV(U2X0);
72 80
#else //Baud rate is defined in the header file, we should not get here
73
  return;
81
  return 0;
74 82
#endif
75 83

  
76 84
  /*Enable receiver and transmitter */
......
84 92
  /* Open the stdio stream corresponding to this port */
85 93
  usb_fd = fdevopen(usb_putc, usb_getc);
86 94
#endif
95

  
96
  usb_initd = 1;
97
  return 0;
98

  
87 99
}
88 100

  
89 101
/**
......
91 103
 * This must be called before any other xbee function
92 104
 * may be used.
93 105
 **/
94
void xbee_init() {
106
int xbee_init() {
107

  
108
  if(xbee_initd) {
109
    return ERROR_INIT_ALREADY_INITD;
110
  }
111

  
95 112
  //Set baud rate
96 113
  // - 115200 (both wired and wireless) is UBRR=8, U2X=1
97 114
  // - 9600 is U2X =1, UBRR = 107.
......
104 121
  UBRR1L = 103;
105 122
  UCSR1A |= _BV(U2X1);
106 123
#else //Baud rate is defined in the header file, we should not get here
107
  return;
124
  return 0;
108 125
#endif
109 126

  
110 127
  //Enable receiver and transmitter
......
118 135
  /* Open the stdio stream corresponding to this port */
119 136
  xbee_fd = fdevopen(xbee_putc, xbee_getc);
120 137
#endif
138

  
139
  xbee_initd = 1;
140
  return 0;
141

  
121 142
}
122 143

  
123 144
/**
......
127 148
 * @return 0 for success, nonzero for failure
128 149
 **/
129 150
int usb_putc(char c) {
151

  
152
  if(!usb_initd)
153
    return ERROR_LIBRARY_NOT_INITD;
154

  
130 155
  // Wait until buffer is clear for sending
131 156
  loop_until_bit_is_set(UCSR0A, UDRE0);
132 157
	
......
142 167
 * @return 0 for success, nonzero for failure
143 168
 **/
144 169
int xbee_putc(char c) {
170

  
171
  if(!xbee_initd)
172
    return ERROR_LIBRARY_NOT_INITD;
173

  
145 174
  // Wait until buffer is clear for sending
146 175
  loop_until_bit_is_set(UCSR1A, UDRE1);
147 176
	
......
158 187
 **/
159 188
int usb_puts(char *s) {
160 189
  char *t = s;
190

  
191
  if(!usb_initd)
192
    return ERROR_LIBRARY_NOT_INITD;
193

  
161 194
  while (*t != 0) {
162 195
    usb_putc(*t);
163 196
    t++;
......
169 202
 * Sends a sequence of characters from program space over USB.
170 203
 *
171 204
 * @param s the string to send
205
 *
206
 * @return 0 if init succesfull, an error code otherwise
172 207
 **/
173
void usb_puts_P (PGM_P s) {
208
int usb_puts_P (PGM_P s) {
174 209
    char buf;
210

  
211
    if(!usb_initd)
212
      return ERROR_LIBRARY_NOT_INITD;
175 213
	
176 214
    while (memcpy_P (&buf, s, sizeof (char)), buf!=0) {
177 215
        usb_putc (buf);
178 216
        s++;
179 217
    }
218

  
219
    return 0;
180 220
}
181 221

  
182 222

  
......
186 226
 * This function blocks execution until a character has been received.
187 227
 * xbee_init must be called before this function may be used.
188 228
 * 
189
 * @return the first character in the usb buffer
229
 * @return the first character in the usb buffer, -1 on error
190 230
 *
191 231
 * @see usb_init, usb_getc_nb
192 232
 **/
193 233
int usb_getc(void) {
234

  
235
  if(!usb_initd)
236
    return -1;
237

  
194 238
  // Wait for the receive buffer to be filled
195 239
  loop_until_bit_is_set(UCSR0A, RXC0);
196 240
	
......
204 248
 * received. xbee_init must be called before this function
205 249
 * may be used.
206 250
 * 
207
 * @return the first character in the xbee buffer
251
 * @return the first character in the xbee buffer, -1 on error
208 252
 * 
209 253
 * @see xbee_init, xbee_getc_nb
210 254
 **/
211 255
int xbee_getc(void) {
256

  
257
  if(!usb_initd)
258
    return -1;
259

  
212 260
  // Wait for the receive buffer to be filled
213 261
  loop_until_bit_is_set(UCSR1A, RXC1);
214 262
	
......
224 272
 * @param c the received character. This will be set if a character has
225 273
 * been received.
226 274
 * 
227
 * @return -1 if no character is available, 0 otherwise
275
 * @return -1 if no character is available, 0 otherwise, positive for error
228 276
 * 
229 277
 * @see usb_init, usb_getc
230 278
 **/
231 279
int usb_getc_nb(char *c) {
280

  
281
  if(!usb_initd)
282
    return ERROR_LIBRARY_NOT_INITD;
283

  
232 284
  // check if the receive buffer is filled
233 285
  if (UCSR0A & _BV(RXC0)) {
234 286
    // Read the receive buffer
......
248 300
 * @param c the received character. This will be set if a character has
249 301
 * been received.
250 302
 * 
251
 * @return -1 if no character is available, 0 otherwise
303
 * @return -1 if no character is available, 0 otherwise, positive for error
252 304
 *
253 305
 * @see xbee_init, xbee_getc
254 306
 **/
255 307
int xbee_getc_nb(char *c) {
308
  if(!xbee_initd)
309
    return ERROR_LIBRARY_NOT_INITD;
310

  
256 311
  // check if the receive buffer is filled
257 312
  if (UCSR1A & _BV(RXC1)) {
258 313
    // Read the receive buffer
......
284 339
int usb_puti(int value ) {
285 340
  unsigned char usb_data[6]={'0','0','0','0','0','0' }, position=sizeof(usb_data), radix=10; 
286 341

  
342
  if(!usb_initd)
343
    return ERROR_LIBRARY_NOT_INITD;
344

  
345

  
287 346
  /* convert int to ascii  */ 
288 347
  if(value<0) { 
289 348
    usb_putc('-'); 
......
329 388
 * @param value the value to print
330 389
 * 
331 390
 * @see usb_init, usb_puti, usb_puts, usb_puth8, hex_digit
391
 *
392
 * @return 0 if init succesfull, an error code otherwise
332 393
 **/
333
void usb_puth16 (uint16_t value)
394
int usb_puth16 (uint16_t value)
334 395
{
396
    if(!usb_initd)
397
      return ERROR_LIBRARY_NOT_INITD;
398

  
335 399
    usb_putc (hex_digit((value >>12)&0xF));
336 400
    usb_putc (hex_digit((value >>8 )&0xF));
337 401
    usb_putc (hex_digit((value >>4 )&0xF));
338 402
    usb_putc (hex_digit( value      &0xF));
403

  
404
    return 0;
339 405
}
340 406

  
341 407
/**
......
346 412
 * @param value the value to print
347 413
 * 
348 414
 * @see usb_init, usb_puti, usb_puts, usb_puth16, hex_digit
415
 *
416
 * @return 0 if init succesfull, an error code otherwise
349 417
 **/
350
void usb_puth8(uint8_t value)
418
int usb_puth8(uint8_t value)
351 419
{
420
    if(!usb_initd)
421
      return ERROR_LIBRARY_NOT_INITD;
422

  
352 423
    usb_putc (hex_digit ((value)>>4 &0xF));
353 424
    usb_putc (hex_digit ( value     &0xF));
425

  
426
    return 0;
354 427
}
355 428

  
trunk/code/projects/libdragonfly/dragonfly_lib.h
41 41
 * @{
42 42
 **/
43 43

  
44
//return value definitions
45
#define ERROR_INIT_FAILED 1
46
#define ERROR_INIT_ALREADY_INITD 2
47

  
48
#define ERROR_LIBRARY_NOT_INITD 3
49

  
44 50
// Configuration definitions
45 51
/** @brief Initialize analog **/
46 52
#define ANALOG 0x01
trunk/code/projects/libdragonfly/serial.h
68 68
#ifndef _SERIAL_H
69 69
#define _SERIAL_H
70 70

  
71
#include <dragonfly_lib.h>
71 72
#include <inttypes.h>
72 73
#include <avr/pgmspace.h>
73 74

  
......
87 88
#endif
88 89

  
89 90
/** @brief Initialize the USB **/
90
void usb_init(void);
91
int usb_init(void);
91 92
/** @brief Print a character to USB **/
92 93
int usb_putc(char c);
93 94
/** @brief Read a character from USB **/
......
97 98
/** @brief Print a string to USB **/
98 99
int usb_puts(char *s);
99 100
/** @brief Print a string from program space to USB **/
100
void usb_puts_P (PGM_P s);
101
int usb_puts_P (PGM_P s);
101 102
/** @brief Print an integer to USB **/
102 103
int usb_puti(int value);
103 104
/** @brief Determine a hexadecimal digit **/
104 105
uint8_t hex_digit (uint8_t value);
105 106
/** @brief Print a fixed width hexadecimal representation to USB **/
106
void usb_puth16 (uint16_t value);
107
int usb_puth16 (uint16_t value);
107 108
/** @brief Print a fixed width hexadecimal representation to USB **/
108
void usb_puth8(uint8_t value);
109
int usb_puth8(uint8_t value);
109 110
/** @brief Alias for usb_puth16 **/
110 111
static inline void usb_puth (uint16_t value) { usb_puth16 (value); };
111 112

  
......
130 131
#endif
131 132

  
132 133
/** @brief Initialize the XBee **/
133
void xbee_init(void);
134
int xbee_init(void);
134 135
/** @brief Print a character to the XBee **/
135 136
int xbee_putc(char c);
136 137
/** @brief Read a character from the XBee **/
trunk/code/projects/libdragonfly/eeprom.c
1
/**
2
 * @file eeprom.c
3
 * @brief handles eeprom storage for persistent data
4
 *
5
 * Contains functions and definitions for reading and writing to eeprom
6
 *
7
 * @author Colony Project, Brad Neuman
8
 */
9
 
1 10
#include <avr/io.h>
2 11
#include "eeprom.h"
3 12

  
13
/** @brief store a byte to eeproem
14
 *  @return 0 if success, nonzero on failure
15
 */
4 16
int eeprom_put_byte(unsigned int uiAddress, unsigned char ucData) {
5 17
    /* Wait for completion of previous write */
6 18
    while(EECR & (1<<EEWE));
......
15 27
    return 0;
16 28
}
17 29

  
30
/** @brief reads a byte from eeprom
31
 *
32
 *  Pass it thge address and a pointer to a byte where the byte at the
33
 *  address will be stored
34
 *
35
 *  @return 0 if successful (byte is set to the eeprom value at addr), 
36
 *  nonzero if there was a problem
37
 */
18 38
int eeprom_get_byte(unsigned int uiAddress, unsigned char *byte) {
19 39
    /* Wait for completion of previous write */
20 40
    while(EECR & (1<<EEWE));
......
28 48
    return 0;
29 49
}
30 50

  
31

  
51
/** @brief get stored robot ID
52
 *
53
 *  checks that EEPROM has been programed with an ID and returns it
54
 *
55
 *  @return the robot id, if it is stored. If it returns 0xFF it is probably invalid
56
 */
32 57
unsigned char get_robotid(void) {
33 58
    unsigned char c0, c1, c2;
34 59
    
......
41 66
        return 0xFF;
42 67
}
43 68

  
69
/** @brief get stored robot ID
70
 *
71
 * checks that EEPROM has been programed with an BOM type and returns it
72
 *
73
 *  @return the robot bom type as defined in bom.h, if it is stored. If it returns 0xFF it is probably invalid
74
 */
44 75
unsigned char get_bom_type(void) {
45 76
    unsigned char c0, c1, c2, c3;
46 77
    
trunk/code/projects/libdragonfly/spi.c
8 8
#include <avr/interrupt.h>
9 9
#include "spi.h"
10 10

  
11
unsigned char spi_initd=0;
11 12

  
12 13
static volatile char spi_bytes; /* number of bytes to read */
13 14
static spi_fun_recv_t spi_recv_func; /* byte handler */
......
18 19
* 
19 20
* @param recv_func The function to be called for each byte of data received.
20 21
* @param recv_complete_func  The function to be called at the end of a complete transmission.
22
*
23
* @return 0 if init succesfull, an error code otherwise
21 24
*/
22
void spi_init (spi_fun_recv_t recv_func, spi_fun_recv_complete_t recv_complete_func)
25
int spi_init (spi_fun_recv_t recv_func, spi_fun_recv_complete_t recv_complete_func)
23 26
{
27
    if(spi_initd) {
28
      return ERROR_INIT_ALREADY_INITD;
29
    }
30

  
24 31
    /*  Enable Interrupt, Enable SPI Module, MSB First, Master Mode, Clock div = 64 */
25 32
    SPCR = _BV(SPE) | _BV(SPIE) /*| _BV(DORD)*/ | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
26 33
    SPSR = _BV(SPI2X); 
......
37 44
    spi_recv_complete_func = recv_complete_func;
38 45
    spi_bytes = 0;
39 46
    //usb_puts("\tspi.c Debug: SPI INITIALIZED\n");
47

  
48
    spi_initd=1;
49
    return 0;
40 50
}
41 51

  
42 52
/** 
......
44 54
* 
45 55
* @param bytes The number of bytes to be transferred.
46 56
**/
47
void spi_transfer(char bytes)
57
int spi_transfer(char bytes)
48 58
{
59
    if(!spi_initd)
60
      return ERROR_LIBRARY_NOT_INITD;
61

  
49 62
    spi_bytes = bytes;
50 63
    PORTB &= ~SS; /* Set SS low to initiate transmission */
51 64
    SPDR = 0xff; /* Initiate data transmision */
65

  
66
    return 0;
52 67
}
53 68

  
54 69
ISR(SIG_SPI) 
trunk/code/projects/libdragonfly/eeprom.h
1
/**
2
 * @file eeprom.h
3
 * @brief handles eeprom storage for persistent data
4
 *
5
 * Contains functions and definitions for reading and writing to eeprom
6
 *
7
 * @author Colony Project, Brad Neuman
8
 */
9
 
10 1
 #ifndef _EEPROM_H_
11 2
 #define _EEPROM_H_
12 3
 
13 4
 #define EEPROM_ROBOT_ID_ADDR 0x10
14 5
 #define EEPROM_BOM_TYPE_ADDR 0x14
15 6
 
16
 /** @brief store a byte to eeproem
17
  *  @return 0 if success, nonzero on failure
18
  */
19 7
 int eeprom_put_byte(unsigned int addr, unsigned char byte);
20 8
 
21
 /** @brief reads a byte from eeprom
22
  *
23
  *  Pass it thge address and a pointer to a byte where the byte at the
24
  *  address will be stored
25
  *
26
  *  @return 0 if successful (byte is set to the eeprom value at addr), 
27
  *  nonzero if there was a problem
28
   */
29 9
 int eeprom_get_byte(unsigned int addr, unsigned char *byte);
30 10
 
31
 /** @brief get stored robot ID
32
  *
33
  *  checks that EEPROM has been programed with an ID and returns it
34
  *
35
  *  @return the robot id, if it is stored. If it returns 0xFF it is probably invalid
36
  */
37 11
 unsigned char get_robotid(void);
38 12
  
39
   /** @brief get stored robot ID
40
  *
41
  * checks that EEPROM has been programed with an BOM type and returns it
42
  *
43
  *  @return the robot bom type as defined in bom.h, if it is stored. If it returns 0xFF it is probably invalid
44
  */
45 13
 unsigned char get_bom_type(void);
46 14
 
47 15
 #endif
trunk/code/projects/libdragonfly/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

  
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
 **/
63 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

  
63

  
64 64
/* Calculate how many cycles to delay for to get 1 ms. Based on F_CPU which should be defined by the makefile */
65 65
#ifdef F_CPU
66 66
#define WAIT_CYCLES ((F_CPU / 1000) / 10)
67 67
#else
68 68
#define WAIT_CYCLES (8000 / 10)
69 69
#endif
70

  
71
static volatile int _rtc_val = 0;
72
static volatile int _rtc_pulse = 0;
73
static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
74
static void (*_rtc_f)(void) = 0;
75 70

  
76 71

  
77

  
78
/**
79
 * @defgroup time Time
80
 * @brief Time functions
81
 * 
82
 * Functions dealing with time.
83
 * 
84
 * @{
85
 **/
86

  
87
/**
88
 * Delays for the specified number of milliseconds.
72
unsigned char time_initd = 0;
73

  
74
static volatile int _rtc_val = 0;
75
static volatile int _rtc_pulse = 0;
76
static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
77
static void (*_rtc_f)(void) = 0;
78

  
79

  
80

  
81
/**
82
 * @defgroup time Time
83
 * @brief Time functions
84
 * 
85
 * Functions dealing with time.
86
 * 
87
 * @{
88
 **/
89

  
90
/**
91
 * Delays for the specified number of milliseconds.
89 92
 * It depends on F_CPU to be defined in order to calculate how many cycles
90 93
 * it should delay. If it is not defined, a default clock of 8MHz is assumed.
91 94
 * 
92 95
 * We use _delay_loop_2 which will run assembly instructions that should be
93 96
 * 4 cycles long. Optimizations must be enabled for this to be true.
94 97
 * That function is called to ensure around 1ms per execution. To generate
95
 * multiple ms we run a for loop of how many milliseconds are desired.

98
 * multiple ms we run a for loop of how many milliseconds are desired.
96 99
 *
97 100
 * The error should be just the skew on the oscillator as the formula to 
98 101
 * calculate delay cycles should always be a whole number. The is some skew
99 102
 * in practice though it is unavoidable. Delaying for less than 1s should make
100 103
 * the error negligable.
101
 *

102
 * @param ms the number of milliseconds to delay for

103
 **/

104
 *
105
 * @param ms the number of milliseconds to delay for
106
 **/
104 107
void delay_ms(int ms) {
105 108
    for (; ms > 0; ms--) {
106 109
        _delay_loop_2(WAIT_CYCLES);
107 110
    }
108 111
}
109 112

  
110

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

  
147
  /* 	Enable Output Compare A Interrupt. When OCR3A is met by the timer TCNT3 this interrupt will be
148
	triggerd. (See page140 in Atmega128 Docs for more information */
149
  ETIMSK |= _BV(OCIE3A);
150
	
151
  /*	Store the pointer to the function to be used in the interrupt */
152
  _rtc_f = rtc_func;
153
	
154
  /*	Store how many 1/16ths of a second you want to let by before triggering an interrupt */
155
  _rtc_scale = prescale_opt;
156
}
157

  
158
/**
159
 * Returns the time elapsed in seconds since the last call to
160
 * rtc_init or rtc_reset.
161
 *
162
 * @return the number of seconds since the last call to rtc_init or rtc_reset
163
 *
164
 * @see rtc_init, rtc_reset
165
 **/
166
int rtc_get(void) {
167
  return _rtc_val;
168
}
169

  
170
/**
171
 * Resets the real time clock counter to 0.
172
 *
173
 * @see rtc_init, rtc_get
174
 **/
175
void rtc_reset(void) {
176
  _rtc_val = 0;
177
}
178

  
179
/** @} **/ //end defgroup
180

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

  
186
  if (_rtc_pulse ==  _rtc_scale) {
187
    //Increment the real time clock counter
188
    _rtc_val++;
189
		
190
    //Calls the function tied to the real time clock if defined
191
    if(_rtc_f != 0)
192
      _rtc_f();
193
		
194
    //Resets the pulse until the next scale is matched
195
    _rtc_pulse = 0;
196
  }	
197
	
198
  //Updates the amount of pulses seen since the last scale match
199
  _rtc_pulse++;
200
	
201
}
113

  
114
/* 	Prescales defined in time.h. SECOND will give you 1 second.
115
	More scales are defined in the time.h file.
116
	rtc_func is the address to a function that you want called every clock tick. */
117
/**
118
 * Initializes the real time clock. Prescales are defined in time.h.
119
 * For example, SECOND will give 1 second. The specified function is
120
 * called every clock tick. For the real time clock to activate,
121
 * interrupts must be enabled. (through sei() )
122
 *
123
 * @param prescale_opt the period with which the timer is triggered
124
 * @param rtc_func the function called when the timer is triggered
125
 *
126
 * @return 0 if init succesfull, an error code otherwise
127
 *
128
 * @see rtc_get, rtc_reset
129
 *
130
 **/
131
int rtc_init(int prescale_opt, void (*rtc_func)(void)) {
132

  
133
  if(time_initd) {
134
    return ERROR_INIT_ALREADY_INITD;
135
  }
136
	
137
  //Clear timer register for Timer 3
138
  TCNT3 = 0;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff