diff --git a/Makefile b/Makefile index b874eeb..d736360 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CFLAGS += -Wall -Os -I. -mmcu=attiny26 -std=c99 DEFINES += -DF_CPU=16e6 -OBJECTS = gg.o mmc.o +OBJECTS = gg.o mmc.o #ringbuf_small.o # further optimization: # this removes dead code and does global linker optimization diff --git a/README b/README index ef50282..abab41e 100644 --- a/README +++ b/README @@ -1,3 +1,19 @@ +pin belegung: + +PA0 - MMC - +PA1 - MMC - +PA2 - MMC - +PA3 - MMC - + +PA7 - "Ausschalter" + +PB0 - Progger - MOSI +PB1 - Progger - MISO +PB2 - Progger - SCK +PB3 - Speaker + +PB7 - Reset + mmc-code from http://www.ulrichradig.de/home/index.php/avr/mmc-sd diff --git a/TODO b/TODO index 17b9e30..fbc2948 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,6 @@ - 11bit-pwm-emu - drumherum - data-streaming von sdcard - - ringbuf (ryx) - testen - sdcard diff --git a/gg.c b/gg.c index db968ba..da422e5 100644 --- a/gg.c +++ b/gg.c @@ -2,6 +2,7 @@ #include #include +#include "ringbuf_small.h" #include "ringbuf_small.c" #include "mmc.h" @@ -17,30 +18,22 @@ void timer_init_tiny26(void) 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); + OCR1B = 0; + cnt_to_next = 1;/* overflows to next sample */ + + TCCR1A = (1 << COM1B1) | (1 << PWM1B);/* pwm enable, not inverted */ + TCCR1B = (1 << CS11) | (1 << CS10);/* fast pwm, prescaler / 2 */ + DDRB |= (1 << PB3); TIMSK = 1 << TOIE1;/* interrupt on overflow */ } +#define BUFFER_SIZE 32 +uint16_t buffer[BUFFER_SIZE];/* buffer for mmc data */ +ringbuf_t rb; +uint32_t length;/* remaining samples */ -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) +/*ISR(TIMER1_OVF1_vect, ISR_NAKED) { __asm__("in r2, 0x3f"); // save sreg if(--cnt_to_ocr_incr){ @@ -48,34 +41,53 @@ ISR(TIMER1_OVF1_vect, ISR_NAKED) } 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 + __asm__("out 0x3f,r2"); // restore sreg reti(); -} +}// */ +ISR(TIMER1_OVF1_vect){ + // next try: simplistic, not too much looking at speed + uint16_t next = 0; + + if(!--cnt_to_next){ + ringbuf_get(&rb, &next); + OCR1B = next>>8; + cnt_to_ocr_incr = 8 - (next & 0x7); + cnt_to_next = 8; + if(!--length) + { + /* shut down */ + PORTA &= ~(1 << PA7); + } + } else { + if(!--cnt_to_ocr_incr){ + OCR1B += 1; + } + } +} int main(void) __attribute__((noreturn)); int main(void) { - uint8_t ref; // TODO: what does this do? + DDRA |= (1 << PA7); + PORTA |= (1 << PA7); + ringbuf_init(&rb, buffer, BUFFER_SIZE); if(mmc_init() != 0) {/* mmc fail */;} + + mmc_read_part(0, (unsigned char *) &length, 4); + timer_init_tiny26(); sei(); - for(;;) + unsigned long block = 0; + for(;; block++) { - 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; - } + mmc_read_to_ringbuffer(block, &rb); } } diff --git a/gg.h b/gg.h index a2f2eb1..e97ca8c 100644 --- a/gg.h +++ b/gg.h @@ -11,3 +11,4 @@ register uint8_t next_cnt_to_incr __asm__("r6"); register uint8_t cnt_to_next __asm__("r7"); register uint8_t needs_new_data_flag __asm__("r8"); +extern ringbuf_t rb; diff --git a/mmc.c b/mmc.c index d31b202..11e6808 100644 --- a/mmc.c +++ b/mmc.c @@ -135,24 +135,22 @@ unsigned char mmc_read_byte (void) unsigned char Byte = 0; #if SPI_Mode //Routine für Hardware SPI SPDR = 0xff; - while(!(SPSR & (1<0; a--) //das Byte wird Bitweise nacheinander Empangen MSB First - { + for(unsigned char a=8; a>0; a--) //das Byte wird Bitweise nacheinander Empangen MSB First + { MMC_Write &=~(1< 0) //Lesen des Pegels von MMC_DI - { - Byte |= (1<<(a-1)); - } - else - { - Byte &=~(1<<(a-1)); - } - MMC_Write |=(1< 0) //Lesen des Pegels von MMC_DI + { + Byte |= 1; } + Byte <<= 1; + MMC_Write |=(1<0; a--) //das Byte wird Bitweise nacheinander Gesendet MSB First + for(uint8_t current_bit = 1 << 7; current_bit; current_bit >>= 1) //das Byte wird Bitweise nacheinander Gesendet MSB First { - if (bit_is_set(Byte,(a-1))>0) //Ist Bit a in Byte gesetzt - { - MMC_Write |= (1<>24 ); + cmd[2] = ((addr & 0x00FF0000) >>16 ); + cmd[3] = ((addr & 0x0000FF00) >>8 ); + + mmc_read_block_part(cmd, Buffer, count, 512); +} + +//############################################################################ +//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) +void mmc_read_block_to_ringbuffer(unsigned char *cmd, ringbuf_t *buffer, unsigned int Bytes) +//############################################################################ +{ + //Sendet Commando cmd an MMC/SD-Karte + if (mmc_write_command (cmd) != 0) + { + return; + } + //Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte) + while(mmc_read_byte() != 0xfe) {;} + + uint16_t data = 0; + + //Lesen des Bolcks (normal 512Bytes) von MMC/SD-Karte + for (unsigned int a=0;a>24 ); + cmd[2] = ((addr & 0x00FF0000) >>16 ); + cmd[3] = ((addr & 0x0000FF00) >>8 ); + + mmc_read_block_to_ringbuffer(cmd, buffer, 512); +} + //############################################################################ //Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) unsigned char mmc_read_cid (unsigned char *Buffer) diff --git a/mmc.h b/mmc.h index 11dd25a..09d9d38 100644 --- a/mmc.h +++ b/mmc.h @@ -8,9 +8,13 @@ Copyright (C) 2004 Ulrich Radig #define _MMC_H_ #include +#include + +#include "ringbuf_small.h" //#define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI #define SPI_Mode 0 +#define WAIT_HALF_CLOCK _delay_us(1) #define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI #define MMC_Read PINB @@ -60,6 +64,14 @@ extern unsigned char mmc_init(void); extern unsigned char mmc_read_sector (unsigned long,unsigned char *); +extern void mmc_read_block_part(unsigned char *, unsigned char *, uint16_t, unsigned int); + +extern void mmc_read_part(unsigned long, unsigned char *, uint16_t); + +extern void mmc_read_block_to_ringbuffer(unsigned char *, ringbuf_t *, unsigned int); + +extern void mmc_read_to_ringbuffer(unsigned long, ringbuf_t *); + extern unsigned char mmc_write_sector (unsigned long,unsigned char *); extern unsigned char mmc_write_command (unsigned char *); @@ -77,5 +89,3 @@ extern unsigned char mmc_read_cid (unsigned char *); #define nop() __asm__ __volatile__ ("nop" ::) #endif //_MMC_H_ - - diff --git a/ringbuf_small.c b/ringbuf_small.c index 360d3e9..9be5caa 100644 --- a/ringbuf_small.c +++ b/ringbuf_small.c @@ -10,11 +10,11 @@ * - reading of pointers allowed at any time * - volatile not really necessary, unless you really need the functions to * react to freespace/newdata while they're running - * + * * PUT AND GET ARE NOT REENTRANT! */ -void ringbuf_init(ringbuf_t *rb, uint16_t * buf, uint8_t size){ +void ringbuf_init(ringbuf_t *rb, uint16_t *buf, uint8_t size){ rb->startptr = buf; rb->size = size; rb->readpos = 0; @@ -41,9 +41,9 @@ uint8_t ringbuf_put(ringbuf_t *rb, uint16_t value){ } /* gets a value from the ringbuffer - * returns 0 on success, -1 on buffer empty + * returns 0 on success, 1 on buffer empty */ -int8_t ringbuf_get(ringbuf_t *rb, uint16_t* data){ +uint8_t ringbuf_get(ringbuf_t *rb, uint16_t *data){ //uint16_t value; uint8_t next; // calculate next ptr pos @@ -53,16 +53,9 @@ int8_t ringbuf_get(ringbuf_t *rb, uint16_t* data){ } //check for empty if(rb->readpos == rb->writepos){ - return(-1); + return(1); } *data = *(rb->startptr + rb->readpos); rb->readpos = next; return(0); } - - - - - - - diff --git a/ringbuf_small.h b/ringbuf_small.h index 220c43f..8683c2c 100644 --- a/ringbuf_small.h +++ b/ringbuf_small.h @@ -5,14 +5,14 @@ typedef struct { uint16_t* startptr; - uint16_t size; - uint16_t readpos; - uint16_t writepos; + uint8_t size; + uint8_t readpos; + uint8_t writepos; } ringbuf_t; -void ringbuf_init(ringbuf_t* rb, uint16_t* buf, uint8_t size); +void ringbuf_init(ringbuf_t* rb, uint16_t *buf, uint8_t size); uint8_t ringbuf_put(ringbuf_t *rb, uint16_t value); -int8_t ringbuf_get(ringbuf_t *rb, uint16_t* data); +uint8_t ringbuf_get(ringbuf_t *rb, uint16_t *data) __attribute__((always_inline)); #endif