Project

General

Profile

Revision 580

Updated bom.c and bom.h to implement James' changes for BOM1.5

View differences:

branches/rbom/code/projects/libdragonfly/bom.c
39 39
#include "analog.h"
40 40

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

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

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

  
......
77 80
#define MONK3 _PIN_E6     //blue
78 81
#define MONK2 _PIN_E7     //white
79 82

  
80
#define BOM_VALUE_THRESHOLD 200
83
#define BOM_VALUE_THRESHOLD 200
84
#define NUM_BOM_LEDS 16
81 85

  
82 86
/*
83 87
  *The following pin definitions are for the BOM v1.5
......
108 112
 * The BOM is most often use to determine the direction of other
109 113
 * robots. This module contains functions for controlling the BOM.
110 114
 *
111
 * There are currently two versions of the BOM in operation: v1.0
112
 * and v1.5.  v1.5 includes new functionality such as addressable
113
 * emitters, and RSSI range measurement.  If a BOM1.5 is connected
114
 * to a robot, make sure to add a BOM1_5 flag to dragonfly_init().
115
 * 
116 115
 * Include bom.h to access these functions.
117 116
 *
118 117
 * @{
119
 **/
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
}
120 266

  
121 267

  
122 268
/**
123
 * Initializes a BOM1.5 to have all emitters on, and in normal mode.
124
 * With this initialization the BOM1.5 is functionally equivalent to
125
 * BOM1.0
126
 **/
127
void bom_15_init(void) {
128
	is_bom_15 = 1;
129
	bom_set_emitters(0xFFFF);
130
}
131

  
132
/**
133
 * Sets a BOM1.5 to RSSI mode.
134
 **/
135
void bom_RSSI_mode(void) {
136
	output_high(BOM_MODE);
137
}
138

  
139
/**
140
 * Sets a BOM1.5 to normal mode.
141
 **/
142
void bom_normal_mode(void) {
143
	output_low(BOM_MODE);
144
}
145

  
146
/**
147
 * Sets which emitters come on when a BOM1.5 is turned on.
148
 * The LSB of the pattern corresponds to emitter 0, and the 
149
 * MSB corresponds to emitter 15
150
 **/
151
void bom_set_emitters(int pattern) {
152
	int mask = 0x8000;
153
	for(; mask>0; mask=mask>>1)
154
	{
155
		//set the current bit
156
		digital_output(BOM_DATA, 1);
157
		//then pulse the clock
158
		delay_ms(1);
159
		output_high(BOM_CLOCK);
160
		delay_ms(1);
161
		output_low(BOM_CLOCK);
162
	}
163
}
164

  
165
/**
166
 * Returns the direction of the maximum BOM reading,
269
 * (DEPRECATED) Returns the direction of the maximum BOM reading,
167 270
 * as an integer in the range 0-15. 0 indicates to the
168 271
 * robot's right, while the rest of the sensors are
169 272
 * numbered counterclockwise. This is useful for determining
......
176 279
 * @see analog_init
177 280
 **/
178 281
int get_max_bom(void) {
179
	int max_bom_temp = 0;
180
	int a, i, j, h;
181
    h = 255;
182

  
183
    for (j = 0; j < 16; j++)
184
    {
185
      i = lookup[j];
186

  
187
      if (i&8)
188
        output_high(is_bom_15?BOM_S3:MONK3);
189
      else
190
        output_low(is_bom_15?BOM_S3:MONK3);
191

  
192
      if (i&4)
193
        output_high(is_bom_15?BOM_S2:MONK2);
194
      else
195
        output_low(is_bom_15?BOM_S2:MONK2);
196

  
197
      if (i&2)
198
        output_high(is_bom_15?BOM_S1:MONK1);
199
      else
200
        output_low(is_bom_15?BOM_S1:MONK1);
201

  
202
      if (i&1)
203
        output_high(is_bom_15?BOM_S0:MONK0);
204
      else
205
        output_low(is_bom_15?BOM_S0:MONK0);
206

  
207
      a = analog8(is_bom_15?BOM_OUT:MONKI);
208
              
209
      if (a < h)
210
      {
211
        h = a;
212
        max_bom_temp = j;
213
      }
214

  
215
    }
216

  
217
	//threshold on the bom analog value.
218
	//defined in bom.h
219
	// if the analog value read is above the threshold, we cannot see a robot
220
	// (remember, low means higher intensity).
221
	if(h < BOM_VALUE_THRESHOLD) {
222
		return max_bom_temp;
223
	}
224
	else
225
		return -1;
282
    bom_refresh(BOM_ALL);
283
    return bom_get_max();
226 284
}
227 285

  
228 286
/**
229
 * Flashes the BOM. analog_init must be called before this
230
 * function can be used.
287
 * (DEPRECATED) Turns on all bom leds.
231 288
 * 
232
 * @see bom_off, analog_init
289
 * @see bom_off
233 290
 **/
234 291
void bom_on(void)
235 292
{
236
  output_high(is_bom_15?BOM_STROBE:MONKL);
293
  bom_leds_on(BOM_ALL);
237 294
}
238 295

  
239 296
/**
240
 * Stops flashing the BOM. analog_init must be called
241
 * before this function can be used.
297
 * (DEPRECATED) Turns off all bom leds.
242 298
 * 
243
 * @see bom_on, analog_init
299
 * @see bom_on
244 300
 **/
245 301
void bom_off(void)
246 302
{
247
  output_low(is_bom_15?BOM_STROBE:MONKL);
303
    bom_leds_off(BOM_ALL);
248 304
}
249 305

  
250 306
/** @} **/ //end group
307
+static void bom_select(char which) {
308
      if (which&8)
309
        digital_output(MONK3, 1);
310
      else
311
        digital_output(MONK3, 0);
251 312

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

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

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

  
252 329
void output_high(int which) {
253 330
	digital_output(which, 1);
254 331
}
255 333

  
256 334
void output_low(int which) {
257 335
	digital_output(which, 0);
258
}
259

  
336
}
branches/rbom/code/projects/libdragonfly/bom.h
42 42
 * @addtogroup bom
43 43
 * @{
44 44
 **/
45
/** @brief Initializes a BOM v1.5 **/
46
void bom_15_init(void);
47
/** @brief Sets the mode of a BOM v1.5**/
48
void bom_RSSI_mode(void);
49
/** @brief Sets the mode of a BOM v1.5**/
50
void bom_normal_mode(void);
51
/** @brief Sets the emmitter pattern a BOM v1.5**/
52
void bom_set_emitters(int pattern);
53
/** @brief Returns the location of the maximum BOM reading. **/
54
int get_max_bom( void );
55
/** @brief Turns the BOM on. **/
45
 
46
/** @brief Include all elements in the 16-bit bitfield **/
47
#define BOM_ALL 0xFFFF
48
/** @brief Original BOM - No Range, No Individual LED control **/
49
#define BOM     0
50
/** @brief BOM 1.5 - No Range, Individual LED control **/
51
#define BOM15   1
52
/** @brief RBOM - Range, Individual LED control **/
53
#define RBOM    2
54
 
55
/** @brief Initialize the bom according to bom type **/
56
void bom_init(char type);
57
/** @brief Refresh bom_val[] with new values from analog8.  analog_init and bom_init must be called for this to work. **/
58
void bom_refresh(int bit_field);
59
/** @brief Gets the bom reading from bom_val[which].  Call bom_refresh beforehand to read new bom values. **/
60
int bom_get(int which);
61
/** @brief Compares all the values in bom_val[] and returns the index to the highest value element. **/
62
int bom_get_max(void);
63
/** @brief Turns on the selected bom leds. Only works with BOM_ALL if using the original bom. **/
64
void bom_leds_on(int bit_field);
65
/** @brief Turns off the selected bom leds. Only works with BOM_ALL if using the original bom. **/
66
void bom_leds_off(int bit_field);
67

  
68
/** @brief (DEPRECATED) Gets and compares all bom values.  Returns the index to the highest value element. **/
69
int get_max_bom(void);
70
/** @brief (DEPRECATED) Turns on all bom leds. **/
56 71
void bom_on(void);
57
/** @brief Turns the BOM off. **/
72
/** @brief (DEPRECATED) Turns off all bom leds. **/
58 73
void bom_off(void);
59 74

  
60 75
/** @} **/

Also available in: Unified diff