#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#include "ringbuf_small.h"
#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
ringbuf_t rb;

#define BUFFER_SIZE 32
uint16_t buffer[BUFFER_SIZE];/* buffer for mmc data */

/*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 0x3f,r2"); // restore sreg
    reti();
}//*/

ISR(TIMER1_OVF1_vect){
    // next try: simplistic, not too much looking at speed
    uint16_t next;

    if(--cnt_to_next){
        ringbuf_get(&rb, &next);
        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)
{
	ringbuf_init(&rb, buffer, BUFFER_SIZE);
	if(mmc_init() != 0) {/* mmc fail */;}
	
	mmc_read_part(0, length, 4);
	
	timer_init_tiny26();
	sei();
	
	unsigned long block = 0;
	for(;; block++)
	{
		mmc_read_to_ringbuffer(block, &rb);
	}
}
