Project

General

Profile

Revision 1461

Added by Brad Neuman over 14 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:

analog.c
49 49
 * @{
50 50
 **/
51 51

  
52
unsigned char analog_initd=0;
53

  
52 54
volatile int adc_loop_status = ADC_LOOP_STOPPED;
53 55
volatile int adc_sig_stop_loop = 0;
54 56
volatile int adc_current_port = 0;
......
58 60
 * Initializes the ADC.
59 61
 * Call analog_init before reading from the analog ports.
60 62
 *
63
 * @return returns 0 on success, nonzero on error
64
 *
61 65
 * @see analog8, analog10, analog_get8, analog_get10
62 66
 *
63 67
 * @bug First conversion takes a performance penalty of
......
73 77
 * determine highest clock speed for accurate 8-bit ADC.
74 78
 *
75 79
 **/
76
void analog_init(int start_conversion) {
77
	for (int i = 0; i < 11; i++) {
78
		an_val[i].adc10 = 0;
79
		an_val[i].adc8 = 0;
80
	}
80
int analog_init(int start_conversion) {
81
  if(analog_initd)
82
    return ERROR_INIT_ALREADY_INITD;
81 83

  
82
	// ADMUX register
83
	// Bit 7,6 - Set voltage reference to AVcc (0b01)
84
	// Bit 5 - ADLAR set to simplify moving from register
85
	// Bit 4 - X
86
	// Bit 3:0 - Sets the current channel
87
	// Initializes to read from AN1 first (AN0 is reservered for the BOM)
88
	ADMUX = 0;
89
	ADMUX |= ADMUX_OPT | _BV(MUX0);
84
  for (int i = 0; i < 11; i++) {
85
    an_val[i].adc10 = 0;
86
    an_val[i].adc8 = 0;
87
  }
90 88

  
91
	// ADC Status Register A
92
	// Bit 7 - ADEN is set (enables analog)
93
	// Bit 6 - Start conversion bit is set (must be done once for free-running mode)
94
	// Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW
95
	// Bit 4 - ADC interrupt flag, 0
96
	// Bit 3 - Enable ADC Interrupt (required to run free-running mode)
97
	// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz
98
	ADCSRA = 0;
99
	ADCSRA |= _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
89
  // ADMUX register
90
  // Bit 7,6 - Set voltage reference to AVcc (0b01)
91
  // Bit 5 - ADLAR set to simplify moving from register
92
  // Bit 4 - X
93
  // Bit 3:0 - Sets the current channel
94
  // Initializes to read from AN1 first (AN0 is reservered for the BOM)
95
  ADMUX = 0;
96
  ADMUX |= ADMUX_OPT | _BV(MUX0);
97

  
98
  // ADC Status Register A
99
  // Bit 7 - ADEN is set (enables analog)
100
  // Bit 6 - Start conversion bit is set (must be done once for free-running mode)
101
  // Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW
102
  // Bit 4 - ADC interrupt flag, 0
103
  // Bit 3 - Enable ADC Interrupt (required to run free-running mode)
104
  // Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz
105
  ADCSRA = 0;
106
  ADCSRA |= _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
100 107
	
101
	// Set external mux lines to outputs
102
	DDRG |= 0x1C;
108
  // Set external mux lines to outputs
109
  DDRG |= 0x1C;
103 110
	
104
	// Set up first port for conversions
105
	set_adc_mux(0x00);
106
	adc_current_port = AN1;
111
  // Set up first port for conversions
112
  set_adc_mux(0x00);
113
  adc_current_port = AN1;
107 114

  
108
	//Start the conversion loop if requested
109
	if (start_conversion)
110
		analog_start_loop();
115
  //Start the conversion loop if requested
116
  if (start_conversion)
117
    analog_start_loop();
111 118
		
112
	//Conversion loop disabled by default
119
  //Conversion loop disabled by default
120

  
121
  analog_initd=1;
122
  return 0;
113 123
}	
114 124

  
115 125
/**
......
170 180
 * Starts the analog update loop. Will continue to run
171 181
 * until analog_stop_loop is called.
172 182
 *
183
 * @return returns 0 on success, nonzero on error
184
 *
173 185
 * @see analog_stop_loop, analog_loop_status
174 186
 **/
175
void analog_start_loop(void) {
176
	if(adc_loop_status != ADC_LOOP_RUNNING){
177
		//Start the conversion, enable ADC interrupt
178
		ADCSRA |= _BV(ADIE);
179
		ADCSRA |= _BV(ADSC);
180
		adc_loop_status = ADC_LOOP_RUNNING;
181
	}
187
int analog_start_loop(void) {
188
  if(!analog_initd)
189
    return ERROR_LIBRARY_NOT_INITD;
190

  
191
  if(adc_loop_status != ADC_LOOP_RUNNING){
192
    //Start the conversion, enable ADC interrupt
193
    ADCSRA |= _BV(ADIE);
194
    ADCSRA |= _BV(ADSC);
195
    adc_loop_status = ADC_LOOP_RUNNING;
196
  }
197

  
198
  return 0;
182 199
}
183 200

  
184 201
/**
......
187 204
 * is interrupted. No further updates will be made until
188 205
 * the loop is started again.
189 206
 *
207
 * @return returns 0 on success, nonzero on error
208
 *
190 209
 * @see analog_start_loop, analog_loop_status
191 210
 **/
192
void analog_stop_loop() {
193
	//Signal to stop after the next conversion
194
	adc_sig_stop_loop = 1;
211
int analog_stop_loop() {
212
  if(!analog_initd)
213
    return ERROR_LIBRARY_NOT_INITD;
214

  
215
  //Signal to stop after the next conversion
216
  adc_sig_stop_loop = 1;
217

  
218
  return 0;
195 219
}
196 220

  
197 221
/**

Also available in: Unified diff