You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.6 KiB
103 lines
2.6 KiB
#include <avr/io.h>
|
|
#include <util/delay.h>
|
|
#include <avr/interrupt.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
|
|
|
|
#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;
|
|
}
|
|
}
|
|
}
|