#include #include "mmc.h" void timer_init_mega16(void) { ICR1 = (1 << 11) - 1;/* 11 bit pwm */ OCR1A = 0; TCCR1A = (1 << COM1A1) | (1 << CS10) | (1 << WGM11);/* fast pwm, non inverted, top in ICR1 */ TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10);/* fast pwm, top in ICR1, */ DDRD |= (1 << PD5);/* set pwm pin as output */ TIMSK = 1 << TOIE1;/* interrupt at top */ } void timer_init_tiny45(void) { PLLCSR = 1 << PLLE;/* pll enable */ delay_us(100); while(!(PLLCSR & (1 << PLOCK))) {;}/* wait for lock */ PLLCSR |= 1 << PCKE;/* use pll */ OCR1C = 0xff; /* output pin: OC1A = PB1 = 6 */ OCR1A = 0; TCCR1 = (1 << PWM1A) | (1 << COM1A1) | (1 << CS10);/* pwm enable, non inverted, no prescaler */ DDRB |= (1 << PB1); /* output pin: OC1B = PB5 = 3 */ //OCR1B = 0; //TCCR1 = (1 << CS10);/* no prescaler */ //GTCCR = (1 << PWM1B) | (1 << COM1B1);/* pwm enable, non inverted */ //DDRB |= (1 << PB5); TIMSK = 1 << TOIE1;/* interrupt on overflow */ } void timer_init_tiny26(void) { PLLCSR = 1 << PLLE;/* pll enable */ delay_us(100); while(!(PLLCSR & (1 << PLOCK))) {;}/* wait for lock */ PLLCSR |= 1 << PCKE;/* use pll */ OCR1C = 0xff;/* unused */ /* output pin: OC1A = PB1 = 1 or OC1B = PB3 = 2 */ OCR1A = 0; TCCR1A = (1 << COM1A1) (1 << PWM1A);/* pwm enable, not inverted */ TCCR1B = (1 << CS10);/* fast pwm, no prescaler */ DDRB |= (1 << PB1); TIMSK = 1 << TOIE1;/* interrupt on overflow */ } uint8_t length[4];/* remaining samples */ uint8_t mmc_position[4];/* current reading position on mmc */ uint8_t overflows = 1;/* remaining counter overflows until next sample */ #define SAMPLE_BITS 11 #define BUFFER_SIZE 92 #define REFRESH_AMOUNT 64 #define REFRESH_SIZE (BUFFER_SIZE - REFRESH_AMOUNT) uint8_t buffer[BUFFER_SIZE];/* buffer for mmc data */ uint8_t pos = 0;/* current playing position */ uint8_t refresh_buffer = 0;/* position to start buffer refreshing */ timerinterrupt() { //if(!(TIFR & (1 << TOV1))) {continue;}/* interrupt flag polling */ //TIFR |= (1 << TOV1);/* done by hardware */ overflows--; if(!overflows) { overflows = 1 << (SAMPLE_BITS - 8); pos = (pos + 1) % BUFFER_SIZE; } /* TODO: a-law decoding */ /* TODO: 11bit PWM emulation */ OCR1A = buffer[pos];/* play next sample */ } void main(void) { if(mmc_init() != 0) {/* mmc fail */;} timer_init_tiny26(); sei(); for(;;) { if(pos == refresh_buffer)/* refresh buffer if running low */ { mmc_read(mmc_position, buffer + (ref + REFRESH_SIZE) % BUFFER_SIZE, BUFFER_SIZE - ref, buffer, REFRESH_AMOUNT - (BUFFER_SIZE - ref)); /* pos on sd , first buffer address , 1st buffer size ,2nd buf, 2nd buffer size */ refresh_buffer = (refresh_buffer + REFRESH_AMOUNT) % BUFFER_SIZE; } } }