/*

* 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;

}