/*
* MeatPiDSP.c
*
* Created: 06-Oct-20 3:09:07 PM
* Author : Luke
*/
#include <avr/io.h>
#include <avr/interrupt.h>
void GPIOSetup();
void ADCSetup();
void SPISetup();
void TimerSetup();
//2^14
static int a[3] = {13446,-25576,13446};
static int b[3] = {0,-25576,10508};
volatile long y[3];
volatile long x[3];
int IIRFilter(int input);
int main(void)
{
GPIOSetup();
ADCSetup();
SPISetup();
TimerSetup();
sei();
while (1);
}
void GPIOSetup(){
DDRA = 0x00; //Input PA6 and 7 - Analogue in
DDRB = 0xFF; //SPI out
return;
}
void ADCSetup(){
ADMUX |= (1<<REFS0); //AVCC with external capacitor at AREF pin
ADCSRA = (1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2); //enable ADC - clk/2 - ADC to start on timer compare
ADMUX |= 0x07; //ADC7 SingleEnded
SFIOR |= 0x60; //ADC Auto Trigger Source Selections // Timer/Counter0 Compare Match
return;
}
void SPISetup(){
SPCR = 0x50;
return;
}
void TimerSetup(){
TCCR0 = (1<<WGM01); //CTC
OCR0 = 100; //20kHz sampling
TIMSK = (1<<OCIE0);
TCCR0 |= 2; //Prescaler 8
return;
}
ISR(TIMER0_COMP_vect){ //Start interrupt on ADC conversion
while(ADCSRA & 0x40);
int16_t result = IIRFilter(ADC);
unsigned char highres = result>>8;
unsigned char lowres = result;
PORTB &= ~(1<<PB0);
SPDR = ((highres & 0x0F) | 0xB0);
while((SPSR & 0x80) == 0);
highres = SPDR;
SPDR = lowres;
while((SPSR & 0x80) == 0);
lowres = SPDR;
PORTB |= (1<<PB0);
return;
}
int IIRFilter(int input){
x[0] = input;
//Update Delay Lines
//Difference Equation
y[0] =
(a[0] * x[0]
+ a[1] * x[1]
+ a[2] * x[2]
- b[1] * y[1]
- b[2] * y[2])>>14;
x[2]=x[1];
x[1]=x[0];
y[2]=y[1];
y[1]=y[0];
//change to int
int output = (int)y[0]<<2;
return output;
}