| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 | 
							- #include "adc.h"
 
- #include <stdio.h>
 
- #include <avr/io.h>
 
- #include <avr/interrupt.h>
 
- #include <avr/pgmspace.h>
 
- #include <string.h>
 
- #include "pins.h"
 
- static uint8_t adc_count; //used for oversampling
 
- static uint8_t adc_channel_idx; //bitmask index
 
- volatile uint8_t adc_channel; //regular index
 
- volatile uint16_t adc_values[ADC_CHAN_CNT];
 
- static void adc_reset();
 
- static void adc_setmux(uint8_t ch);
 
- void adc_init()
 
- {
 
- 	puts_P(PSTR("adc_init"));
 
-     DIDR0 = ((ADC_CHAN_MSK & ADC_DIDR_MSK) & 0xff); //disable digital inputs PORTF
 
-     DIDR2 = ((ADC_CHAN_MSK & ADC_DIDR_MSK) >> 8); //disable digital inputs PORTK
 
-     ADMUX |= (1 << REFS0); //use AVCC as reference
 
-     //enable ADC, set prescaler/128, enable interrupt
 
-     ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) | (1 << ADIF) | (1 << ADIE);
 
- }
 
- static void adc_reset()
 
- {
 
-     static const uint8_t first_channel_idx = 0;
 
-     static_assert((1 << first_channel_idx) & ADC_CHAN_MSK);
 
-     ADCSRA &= ~(1 << ADSC); //stop conversion just in case
 
-     adc_count = 0;
 
-     adc_channel = 0;
 
-     adc_channel_idx = first_channel_idx;
 
-     adc_setmux(adc_channel_idx);
 
-     memset((void*)adc_values, 0, sizeof(adc_values));
 
- }
 
- static void adc_setmux(uint8_t ch)
 
- {
 
- 	ch &= 0x0f;
 
- 	if (ch & 0x08) ADCSRB |= (1 << MUX5);
 
- 	else ADCSRB &= ~(1 << MUX5);
 
- 	ADMUX = (ADMUX & ~(0x07)) | (ch & 0x07);
 
- }
 
- void adc_start_cycle() {
 
- 	adc_reset();
 
- 	ADCSRA |= (1 << ADSC); //start conversion
 
- }
 
- #ifdef ADC_CALLBACK
 
- extern void ADC_CALLBACK();
 
- #endif //ADC_CALLBACK
 
- ISR(ADC_vect)
 
- {
 
-     adc_values[adc_channel] += ADC;
 
-     if (++adc_count == ADC_OVRSAMPL)
 
-     {
 
-         // go to the next channel
 
-         if (++adc_channel == ADC_CHAN_CNT) {
 
- #ifdef ADC_CALLBACK
 
-             ADC_CALLBACK();
 
- #endif
 
-             return; // do not start the next measurement since there are no channels remaining
 
-         }
 
-         // find the next channel
 
-         while (++adc_channel_idx) {
 
-             if (ADC_CHAN_MSK & (1 << adc_channel_idx)) {
 
-                 adc_setmux(adc_channel_idx);
 
-                 adc_count = 0;
 
-                 break;
 
-             }
 
-         }
 
-     }
 
-     ADCSRA |= (1 << ADSC); //start conversion
 
- }
 
 
  |