#define F_CPU 8000000UL
#include "pins_arduino.h"
#define bufferSize 128
#define BUFFER_MASK (bufferSize-1)
/*
Pinmodes
PB0 MOSI
PB1 MISO
PB2 Clock
PB3 ADC Input
PB4 PWM Out
*/
static struct adc_FIFO {//ringBuffer als struct für pcm saples
byte data[bufferSize];
volatile byte read_ptr; // zeigt auf das Feld mit dem ältesten Inhalt
volatile byte write_ptr; // zeigt immer auf leeres Feld
} adc_buffer = {{}, 8000, 0};
static struct pcm_samples_buffer {//ringBuffer als struct für pcm saples
byte data[bufferSize];
volatile byte read_ptr; // zeigt auf das Feld mit dem ältesten Inhalt
volatile byte write_ptr; // zeigt immer auf leeres Feld
} pcm_buffer = {{}, 0, 0};
void setup() {
cli();
// Enable 64 MHz PLL and use as source for Timer1
PLLCSR = 1 << PCKE | 1 << PLLE;
// Set up Timer/Counter1 for PWM output
TIMSK = 0; // Timer interrupts OFF
TCCR1 = 1 << CS10; //1<<PWM1A | 2<<COM1A0 | 1<<CS10; // PWM A, clear on match, 1:1 prescale
GTCCR = 1 << PWM1B | 2 << COM1B0; // PWM B, clear on match
OCR1B = 128; // 50% duty at start on pin PB4
// Set up Timer/Counter0 for 44.1kHz interrupt to output samples.
TCCR0A = 3 << WGM00; // Fast PWM sets bits WGM00 and WGM01, which (when combined with WGM02 from TCCR0B below) enables Fast PWM mode
TCCR0B = 1 << WGM02 | 2 << CS00; // 1/8 prescale
TIMSK = 1 << OCIE0A; // Enable compare match
OCR0A = 22; // 22us = 44100HZ
//pinModes
pinMode(MOSI, INPUT);// initialize the MOSI Port (PIN 0)
pinMode(MISO, OUTPUT);// initialize the MISO Port (PIN 1)
pinMode(SCK, INPUT);// initialize the SCK Port (PIN 2)
pinMode(4, OUTPUT);
pinMode(3, INPUT);
USICR = (1<<USIWM0) // SPI mode; Uses DO, DI, and USCK pins.
|(1<<USIOIE) // Enable interrupt
|(1<<USICS1) // Clock is external
|(0<<USICS0); // SPI Mode 0
//ADC settings 8bit value
ADMUX = 3 | //channel 3
(1 << ADLAR) | // left shift result
(0 << REFS1) | // Sets ref. voltage to VCC, bit 1
(0 << REFS0); // Sets ref. voltage to VCC, bit 0
ADCSRA =
(1 << ADEN) | // Enable ADC at 38,46 kHz Samplerate
(1 << ADSC) | // start conversion
(1 << ADATE) | // free running
(1 << ADPS2) | // set prescaler to 8, bit 2
(0 << ADPS1) | // set prescaler to 8, bit 1
(0 << ADPS0); // set prescaler to 8, bit 0
sei(); // enable interrupts
}
ISR(ADC_vect)// interuppt each 38kHz
{
byte adcValue = ADCH;
register byte next = ((adc_buffer.write_ptr + 1) & BUFFER_MASK);
if (adc_buffer.read_ptr != next) {
adc_buffer.data[adc_buffer.write_ptr] = adcValue;
//buffer.data[buffer.write_ptr & BUFFER_MASK] = byte;
adc_buffer.write_ptr = next;
}
}
// Sample interrupt 44.1khz
ISR(TIMER0_COMPA_vect) {
if (pcm_buffer.read_ptr != pcm_buffer.write_ptr) {
byte sample = pcm_buffer.data[pcm_buffer.read_ptr];
pcm_buffer.data[pcm_buffer.read_ptr] = 0;
OCR1B = sample;
pcm_buffer.read_ptr = (pcm_buffer.read_ptr + 1) & BUFFER_MASK;
}
}
ISR(USI_OVF_vect){
byte incommingByte = 0;
// Wait for complete byte to arrive
while ((USISR & (1<<USIOIF))==0) {
}
// Clear counter overflow flag so next byte can begin arriving
// While we're processing this one
USISR = (1<<USIOIF);
incommingByte = USIDR;
}
void loop() {
}