#include #include #include #include "ringbuf_small.c" #include "mmc.h" #include "gg.h" 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 */ uint32_t mmc_position;/* current reading position on mmc */ uint8_t overflows = 1;/* remaining counter overflows until next sample */ #define SAMPLE_BITS 11 #define BUFFER_SIZE 64 #define REFRESH_AMOUNT 32 #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 */ /*ISR(TIMER1_OVF1_vect, ISR_NAKED) { __asm__("in r2, 0x3f"); // save sreg if(--cnt_to_ocr_incr){ OCR1A = cur_ocr + 1; } if(--cnt_to_next){ cur_ocr = next_ocr; OCR1A = cur_ocr; cnt_to_ocr_incr = next_cnt_to_incr; cnt_to_next = 8; needs_new_data_flag = 1; } __asm__("out 0x2f,r2"); // restore sreg reti(); }//*/ ISR(TIMER1_OVF1_vect){ // next try: simplistic, not too much looking at speed uint16_t next; if(--cnt_to_next){ next = ringbuf_get(ringbuf); OCR1A = next>>8; cnt_to_ocr_incr = 7-(next & 0x7); cnt_to_next = 7; } else { if(--cnt_to_ocr_incr){ OCR1A += 1; } } } int main(void) __attribute__((noreturn)); int main(void) { uint8_t ref; // TODO: what does this do? if(mmc_init() != 0) {/* mmc fail */;} timer_init_tiny26(); sei(); for(;;) { if(pos == refresh_buffer)/* refresh buffer if running low */ { /* TODO: this won't do. we don't have enough time to read unnecessary bytes -> read data with the same speed as we consume it, keeping a small buffer. */ /* expect 2 bit read from mmc between 2 timer interrupts --> 2 byte read per sample played */ mmc_read_sector(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; } } }