mixer-slider/firmware/slider/adc.c
2019-02-10 19:12:40 +01:00

74 lines
1.4 KiB
C

/*
* adc.c
*
* Created on: 08.02.2019
* Author: julian
*/
#include "adc.h"
#include "main.h"
#include <avr/io.h>
#include <avr/interrupt.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;
// update app state (remap channels)
app.state.state.slider = adc.buffer.ptr[4];
app.state.state.poti[0] = adc.buffer.ptr[3];
app.state.state.poti[1] = adc.buffer.ptr[2];
app.state.state.poti[2] = adc.buffer.ptr[0];
app.state.state.poti[3] = adc.buffer.ptr[1];
}
} 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;
}
/* 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++;
}
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();
}