Project

General

Profile

Statistics
| Revision:

root / branches / rbom / code / projects / libdragonfly / bom.c @ 580

History | View | Annotate | Download (8.49 KB)

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 bom.c
29
 * @brief Implementation for using the BOM
30
 *
31
 * Contains functions for using the Bearing and Orientation Module (BOM)
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

    
36
#include <dragonfly_lib.h>
37
#include "bom.h"
38
#include "dio.h"
39
#include "analog.h"
40

    
41
//constants
42
static const char lookup[16] = {7,6,5,0xe,1,4,3,2,0xf,0,0xd,8,0xc,0xb,9,0xa};
43

    
44
// internal function prototypes
45
static void bom_select(char which);
46

    
47
// internal function prototypes
48
void output_high(int which);
49
void output_low(int which);
50

    
51
/*
52
 Bk R Y (Analog)
53
---------
54
 Green
55
 Blue
56
 White
57
---------
58
 Blue
59
 White
60
*/
61

    
62

    
63
/*
64
the analog pin definitions from dio.h DO NOT work here,
65
so we must use PF0 from avrgcc (as opposed to _PIN_F0).
66
BUT the dio pin definitions from dio.h must be used (no PE...).
67

68
also, _PIN_E2 is initialized to high for some reason,
69
which turns the BOM on when the robot is turned on.
70
WORK-AROUND: call digital_output(_PIN_E2,0) at some point.
71

72
*/
73

    
74
#define MONKI PF0         //analog (yellow)
75
//------------------------//
76
#define MONKL _PIN_E2     //green
77
#define MONK1 _PIN_E3     //blue
78
#define MONK0 _PIN_E4     //white
79
//------------------------//
80
#define MONK3 _PIN_E6     //blue
81
#define MONK2 _PIN_E7     //white
82

    
83
#define BOM_VALUE_THRESHOLD 200
84
#define NUM_BOM_LEDS 16
85

    
86
/*
87
  *The following pin definitions are for the BOM v1.5
88
  */
89

    
90
#define BOM_MODE        _PIN_E2        //dio0
91
#define BOM_STROBE        _PIN_E3        //dio1
92

    
93
#define BOM_DATA        _PIN_A0 //servo0
94
#define BOM_CLOCK        _PIN_A1        //servo1
95

    
96
#define BOM_S0                _PIN_E6        //dio3
97
#define BOM_S1                _PIN_E7        //dio2
98
#define BOM_S2                _PIN_E4        //dio1
99
#define BOM_S3                _PIN_E5        //dio0
100
#define BOM_OUT                PF0                //analog(yellow)
101

    
102
//this is set to 1 if we are using a BOM1.5, and 0 otherwise
103
static char is_bom_15 = 0;
104

    
105
/**
106
 * @defgroup bom BOM (Bearing and Orientation Module)
107
 * @brief Functions for dealing with the BOM.
108
 *
109
 * The Bearing and Orientation Module / Barrel of Monkeys / BOM
110
 * is a custom sensor designed and built by the Colony Project.
111
 * It consists of a ring of 16 IR emitters and 16 IR detectors.
112
 * The BOM is most often use to determine the direction of other
113
 * robots. This module contains functions for controlling the BOM.
114
 *
115
 * Include bom.h to access these functions.
116
 *
117
 * @{
118
 **/
119

    
120
static unsigned int bom_val[NUM_BOM_LEDS];
121
static char bom_type = BOM;
122
  
123
/**
124
 * Initializes the BOM.
125
 * Call bom_init before reading bom values or turning bom leds.
126
 *
127
 * @bugs INCOMPLETE - need to fill in init routine for BOM15
128
 * 
129
 * @see bom_refresh, bom_leds_on, bom_leds_off
130
 **/
131
void bom_init(char type) {
132
    bom_type = type;
133
    
134
    switch(bom_type) {
135
    case BOM:
136
        break;
137
    case BOM15:
138
        is_bom_15 = 1;
139
        //Sets BOM1.5 to normal [BOM] mode
140
        output_low(BOM_MODE);
141
        break;
142
    case RBOM:
143
        break;
144
    //default:
145
    }
146
}
147

    
148
/**
149
 * Iterates through each bit in the bit_field. For each set bit, sets the corresponding bom select bits
150
 *    and updates the corresponding bom value with an analog_get8 reading.  analog_init and bom_init
151
 *    must be called for this to work.
152
 *
153
 *
154
 * @param bit_field specifies which elements in bom_val[] should be updated. Use BOM_ALL to refresh all values.
155
 *    Ex. if 0x0003 is passed, bom_val[0] and bom_val[1] will be updated.
156
 *
157
 * @see bom_get
158
 **/
159
void bom_refresh(int bit_field) {
160
    int i;
161
    
162
    analog_stop_loop();
163
    
164
    for(i = 0; i < NUM_BOM_LEDS; i++) {
165
        if(bit_field & 0x1) {
166
            bom_select(lookup[i]);
167
            bom_val[i] = analog_get8(MONKI);
168
        }
169
        bit_field = bit_field >> 1;
170
    }
171
    
172
    analog_start_loop();
173
}
174

    
175
/**
176
 * Gets the bom reading from bom_val[which].  Call bom_refresh beforehand to read new bom values.
177
 *
178
 * @param which which bom value to return
179
 *
180
 * @return the bom value
181
 *
182
 * see bom_refresh
183
 **/
184
int bom_get(int which) {
185
    return bom_val[which];
186
}
187

    
188
/** 
189
 * Compares all the values in bom_val[] and returns the index to the lowest (max) value element.
190
 *
191
 * @return index to the lowest (max) bom value element.  -1 if no value is lower than
192
 *    BOM_VALUE_THRESHOLD
193
 **/
194
int bom_get_max(void) {
195
    int i, lowest_val, lowest_i;
196
    lowest_i = -1;
197
    lowest_val = 255;
198
    for(i = 0; i < NUM_BOM_LEDS; i++) {
199
        if(bom_val[i] < lowest_val) {
200
            lowest_val = bom_val[i];
201
            lowest_i = i;
202
        }
203
    }
204
    
205
    if(lowest_val < BOM_VALUE_THRESHOLD)
206
        return lowest_i;
207
    else
208
        return -1;
209
}
210

    
211
/**
212
 * Iterates through each bit in the bit_field. For each set bit, turns on the corresponding bom led.
213
 *    bom_init must be called for this to work. Only works with BOM_ALL if using the original bom.
214
 *
215
 * @param bit_field specifies which leds should be turned on.  Use BOM_ALL to turn on all bom leds.
216
 *    Ex. if 0x0005 is passed, leds 0 and 2 will be turned on.
217
 **/
218
void bom_leds_on(int bit_field) {
219
    switch(bom_type) {
220
    case BOM:
221
        if(bit_field == BOM_ALL) {
222
            digital_output(MONKL, 1);
223
        }
224
        break;
225
    case BOM15:
226
        int mask = 0x8000;
227
            for(; mask>0; mask=mask>>1)
228
            {
229
                    //set the current bit
230
                    digital_output(BOM_DATA, 1);
231
                    //then pulse the clock
232
                    delay_ms(1);
233
                    output_high(BOM_CLOCK);
234
                    delay_ms(1);
235
                    output_low(BOM_CLOCK);
236
            }
237
        break;
238
    case RBOM:
239
        //add rbom code here
240
        break;
241
    }
242
}
243

    
244
/**
245
 * Iterates through each bit in the bit_field. For each set bit, turns off the corresponding bom led.
246
 *    bom_init must be called for this to work. Only works with BOM_ALL if using the original bom.
247
 *
248
 * @param bit_field specifies which leds should be turned off.  Use BOM_ALL to turn off all bom leds.
249
 *    Ex. if 0x000B is passed, leds 0 and 3 will be turned off.
250
 **/
251
void bom_leds_off(int bit_field) {
252
    switch(bom_type) {
253
    case BOM:
254
        if(bit_field == BOM_ALL) {
255
            digital_output(MONKL, 0);
256
        }
257
        break;
258
    case BOM15:
259
        //add bom 1.5 code here
260
        break;
261
    case RBOM:
262
        //add rbom code here
263
        break;
264
    }
265
}
266

    
267

    
268
/**
269
 * (DEPRECATED) Returns the direction of the maximum BOM reading,
270
 * as an integer in the range 0-15. 0 indicates to the
271
 * robot's right, while the rest of the sensors are
272
 * numbered counterclockwise. This is useful for determining
273
 * the direction of a robot flashing its BOM, of only one
274
 * robot is currently doing so. analog_init must be called
275
 * before this function can be used.
276
 *
277
 * @return the direction of the maximum BOM reading
278
 *
279
 * @see analog_init
280
 **/
281
int get_max_bom(void) {
282
    bom_refresh(BOM_ALL);
283
    return bom_get_max();
284
}
285

    
286
/**
287
 * (DEPRECATED) Turns on all bom leds.
288
 * 
289
 * @see bom_off
290
 **/
291
void bom_on(void)
292
{
293
  bom_leds_on(BOM_ALL);
294
}
295

    
296
/**
297
 * (DEPRECATED) Turns off all bom leds.
298
 * 
299
 * @see bom_on
300
 **/
301
void bom_off(void)
302
{
303
    bom_leds_off(BOM_ALL);
304
}
305

    
306
/** @} **/ //end group
307

    
308
static void bom_select(char which) {
309
      if (which&8)
310
        digital_output(MONK3, 1);
311
      else
312
        digital_output(MONK3, 0);
313

    
314
      if (which&4)
315
        digital_output(MONK2, 1);
316
      else
317
        digital_output(MONK2, 0);
318

    
319
      if (which&2)
320
        digital_output(MONK1, 1);
321
      else
322
        digital_output(MONK1, 0);
323

    
324
      if (which&1)
325
        digital_output(MONK0, 1);
326
      else
327
        digital_output(MONK0, 0);
328
}
329

    
330
void output_high(int which) {
331
        digital_output(which, 1);
332
}
333

    
334
void output_low(int which) {
335
        digital_output(which, 0);
336
}