76 lines
1.3 KiB
C
76 lines
1.3 KiB
C
/*
|
|
* adc.c
|
|
*
|
|
* Created on: 08.02.2019
|
|
* Author: julian
|
|
*/
|
|
|
|
#include "adc.h"
|
|
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
|
|
#include "led.h"
|
|
|
|
// global adc instance
|
|
volatile adc_t adc;
|
|
|
|
static inline void adc_next() {
|
|
do {
|
|
adc.current_channel = (adc.current_channel+1)%8;
|
|
|
|
if (!adc.current_channel) {
|
|
adc.current_sample = adc.buffer.ptr-1;
|
|
|
|
if (adc.interrupt)
|
|
adc.interrupt(&adc.buffer);
|
|
}
|
|
} while(!(adc.channel_mask & (1<<adc.current_channel)));
|
|
|
|
if (adc.current_sample < (adc.buffer.ptr + adc.buffer.size)) {
|
|
adc.current_sample++;
|
|
}
|
|
|
|
// set mux input
|
|
ADMUX = adc.current_channel;
|
|
}
|
|
|
|
void adc_on_done(adc_interrupt_t interrupt) {
|
|
adc.interrupt = interrupt;
|
|
}
|
|
|
|
/* adc driver */
|
|
void adc_init(adc_buffer_t buffer, uint8_t mask) {
|
|
if (!mask) {
|
|
return;
|
|
}
|
|
|
|
adc.buffer = buffer;
|
|
adc.current_sample = adc.buffer.ptr;
|
|
adc.channel_mask = mask;
|
|
adc.current_channel = 0;
|
|
|
|
// find first channel
|
|
while(!((1<<adc.current_channel) & mask)) {
|
|
adc.current_channel++;
|
|
}
|
|
|
|
adc.interrupt = 0;
|
|
|
|
ADMUX = 0;
|
|
ADCSRA = (1<<ADATE) | (1<<ADEN) ; // enable adc, maximum prescaler value
|
|
}
|
|
|
|
void adc_start() {
|
|
ADCSRA |= (1<<ADIE) | (1<<ADSC); // enable adc interrupt
|
|
}
|
|
|
|
void adc_stop( ){
|
|
ADCSRA &= ~(1<<ADIE);
|
|
}
|
|
|
|
ISR(ADC_vect) {
|
|
*adc.current_sample = ADC;
|
|
adc_next();
|
|
}
|
|
|