Project

General

Profile

Revision 1387

Added by James Kong over 14 years ago

Changed analog to support status checking. Updated bom_refresh to use it.

View differences:

branches/analog/code/projects/libdragonfly/analog.c
49 49
 * @{
50 50
 **/
51 51

  
52
int adc_loop_running = 0;
52
int adc_loop_status = ADC_LOOP_STOPPED;
53
int adc_sig_stop_loop = 0;
53 54
int adc_current_port = 0;
54 55
adc_t an_val[11];
55 56

  
......
104 105
	set_adc_mux(0x00);
105 106
	adc_current_port = AN1;
106 107

  
107
	//Start the conversion if requested
108
	//Start the conversion loop if requested
108 109
	if (start_conversion)
109 110
		analog_start_loop();
110 111
		
......
169 170
 * Starts the analog update loop. Will continue to run
170 171
 * until analog_stop_loop is called.
171 172
 *
172
 * @see analog_stop_loop, analog_loop_running
173
 * @see analog_stop_loop, analog_loop_status
173 174
 **/
174 175
void analog_start_loop(void) {
175 176
	//Start the conversion, enable ADC interrupt
176 177
	ADCSRA |= _BV(ADSC) | _BV(ADIE);
177
	adc_loop_running = 0x1;
178
	adc_loop_status = ADC_LOOP_RUNNING;
178 179
}
179 180

  
180 181
/**
......
183 184
 * is interrupted. No further updates will be made until
184 185
 * the loop is started again.
185 186
 *
186
 * @param Whether or not to block until current conversion
187
 * to complete. Use WAIT_UNTIL_FINISHED or
188
 * SKIP_WAIT.
189
 *
190
 * @see analog_start_loop, analog_loop_running
187
 * @see analog_start_loop, analog_loop_status
191 188
 **/
192
void analog_stop_loop(int skip_wait) {
193
	//Stop the conversion
194
	adc_loop_running = 0x0;
195
	
196
	if(skip_wait) {
197
		//Stop the interrupt
198
		ADCSRA &= _BV(ADIE);
199
		return;
200
	}
201
		
202
	//Wait for the ADC interrupt flag to clear / conversion to complete
203
	while(ADCSRA & _BV(ADIF));
204
	//Stop the interrupt
205
	ADCSRA &= _BV(ADIE);
189
void analog_stop_loop() {
190
	//Signal to stop after the next conversion
191
	adc_sig_stop_loop = 1;
206 192
}
207 193

  
208 194
/**
209
 * Returns the status of loop. 1 for running.
210
 * 0 for not running.
195
 * Returns the status of loop. 0 for stopped.
196
 * 1 for running. 2 for paused.
211 197
 *
212 198
 * @see analog_start_loop, analog_stop_loop
213
 *
214
 * @bug Doesn't actually tell you whether or
215
 * not the loop has fully stopped. adc_loop_running
216
 * is a signalling variable to tell the ISR to stop. 
217
 * need to differentiate the signal from the status.
218 199
 **/
219
int analog_loop_running(void) {
220
	return adc_loop_running;
200
int analog_loop_status(void) {
201
	return adc_loop_status;
221 202
}
222 203

  
223 204
/**
......
339 320

  
340 321

  
341 322
ISR(ADC_vect) {
342
	static volatile int adc_prev_loop_running = 0; 
343 323
	int adc_h = 0;
344 324
	int adc_l = 0;
345 325

  
......
352 332
		an_val[adc_current_port - 1].adc8 = adc_h;
353 333
	}
354 334
	
355
	//Save the result only if we just turned off the loop
356
	if (!adc_loop_running && !adc_prev_loop_running)
357
		return;
358
	
359
	adc_prev_loop_running = adc_loop_running;
360
	
361 335
	//Skip AN7 because it is not a real port
362 336
	if (adc_current_port == AN6) {
363 337
		ADMUX = ADMUX_OPT | EXT_MUX;
......
379 353
		}
380 354
	}
381 355

  
382
	//Initiate next conversion only if we are running a loop
383
	if (!adc_loop_running) {
356
	//Stop loop if signal is set
357
	if(adc_sig_stop_loop) {
358
		//Disable the interrupt
359
		ADCSRA &= _BV(ADIE);
360
		adc_sig_stop_loop = 0;
361
		adc_loop_status = ADC_LOOP_STOPPED;
384 362
		return;
385
    } else {
386
    	ADCSRA |= _BV(ADSC);
387 363
	}
388
		
389
	return;
364
	
365
	//Start next conversion
366
	ADCSRA |= _BV(ADSC);
390 367
}
391 368

  
branches/analog/code/projects/libdragonfly/analog.h
92 92
/** @brief Analog port for the battery voltage detector **/
93 93
#define BATT_PORT  AN11
94 94

  
95
/** @brief Wait for current conversion to complete. Parameter for analog_stop_loop **/
96
#define WAIT_UNTIL_FINISHED 0
97
/** @brief Don't wait for current conversion to complete. Parameter for analog_stop_loop **/
98
#define SKIP_WAIT 1
95
/** @brief Analog loop status. ADC conversion running. **/
96
#define ADC_LOOP_RUNNING 1
97
/** @brief Analog loop status.  No ADC conversion running.**/
98
#define ADC_LOOP_STOPPED 0
99 99

  
100
#define ADC_START 1
101
#define ADC_STOP 0
102

  
103 100
#define ADMUX_OPT 0x60
104 101

  
105 102
/** @brief Struct to hold the value of a particular analog port **/
......
117 114
/** @brief Stops the analog loop. Doesn't do anything if the loop is already stopped. **/
118 115
void analog_stop_loop(void);
119 116
/** @brief Returns the status of the analog loop. **/
120
int analog_loop_running(void);
117
int analog_loop_status(void);
121 118
/** @brief Returns an 8-bit analog value from the look up table. Use this instead of analog_get8. **/
122 119
unsigned int analog8(int which);
123 120
/** @brief Returns an 10-bit analog value from the look up table. Use this instead of analog_get10. **/
branches/analog/code/projects/libdragonfly/bom.c
167 167
 **/
168 168
void bom_refresh(int bit_field) {
169 169
    int i;
170
	int loop_running;
170
	int loop_was_running = 0;
171 171
    
172 172
	//Check analog loop status
173
	loop_running = analog_loop_running();
174
    if(loop_running)
173
    if(analog_loop_status() == ADC_LOOP_RUNNING) {
174
		loop_was_running = 1;
175 175
		analog_stop_loop();
176
	}
176 177
    
178
	//Read BOM values
177 179
    for(i = 0; i < NUM_BOM_LEDS; i++) {
178 180
        if(bit_field & 0x1) {
179 181
            bom_select(i);
......
183 185
    }
184 186
    
185 187
	//Restore analog loop status
186
	if(loop_running)
188
	if(loop_was_running)
187 189
		analog_start_loop();
188 190
}
189 191

  

Also available in: Unified diff