Merge branch 'master' of ghostdub.de:gg-button

master
Hannes 14 years ago
commit f048f9f79a

@ -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

@ -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

@ -9,7 +9,6 @@
- 11bit-pwm-emu
- drumherum
- data-streaming von sdcard
- ringbuf (ryx)
- testen
- sdcard

76
gg.c

@ -2,6 +2,7 @@
#include <util/delay.h>
#include <avr/interrupt.h>
#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);
}
}

@ -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;

156
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<<SPIF))){};
while(!(SPSR & (1 << SPIF))) {;}
Byte = SPDR;
#else //Routine für Software SPI
for (unsigned char a=8; a>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<<SPI_Clock); //erzeugt ein Clock Impuls (Low)
WAIT_HALF_CLOCK;
if (bit_is_set(MMC_Read,SPI_DI) > 0) //Lesen des Pegels von MMC_DI
{
Byte |= (1<<(a-1));
}
else
{
Byte &=~(1<<(a-1));
}
MMC_Write |=(1<<SPI_Clock); //setzt Clock Impuls wieder auf (High)
if(bit_is_set(MMC_Read,SPI_DI) > 0) //Lesen des Pegels von MMC_DI
{
Byte |= 1;
}
Byte <<= 1;
MMC_Write |=(1<<SPI_Clock); //setzt Clock Impuls wieder auf (High)
WAIT_HALF_CLOCK;
}
#endif
return (Byte);
}
@ -165,28 +163,28 @@ void mmc_write_byte (unsigned char Byte)
{
#if SPI_Mode //Routine für Hardware SPI
SPDR = Byte; //Sendet ein Byte
while(!(SPSR & (1<<SPIF))) //Wartet bis Byte gesendet wurde
{
}
while(!(SPSR & (1 << SPIF))) {;}//Wartet bis Byte gesendet wurde
#else //Routine für Software SPI
for (unsigned char a=8; a>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<<SPI_DO); //Set Output High
}
else
{
MMC_Write &= ~(1<<SPI_DO); //Set Output Low
}
if(Byte & current_bit) //Ist Bit a in Byte gesetzt
{
MMC_Write |= (1<<SPI_DO); //Set Output High
}
else
{
MMC_Write &= ~(1<<SPI_DO); //Set Output Low
}
MMC_Write &= ~(1<<SPI_Clock); //erzeugt ein Clock Impuls (LOW)
WAIT_HALF_CLOCK;
MMC_Write |= (1<<SPI_Clock); //setzt Clock Impuls wieder auf (High)
WAIT_HALF_CLOCK;
}
MMC_Write |= (1<<SPI_DO); //setzt Output wieder auf High
#endif
}
#if 0
//############################################################################
//Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte
unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
@ -243,6 +241,7 @@ unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
return(0);
}
#endif
//############################################################################
//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
@ -297,6 +296,111 @@ unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer)
return(0);
}
//############################################################################
//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
void mmc_read_block_part(unsigned char *cmd,unsigned char *Buffer,uint16_t count, 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){};
//Lesen des Bolcks (normal 512Bytes) von MMC/SD-Karte
for (unsigned int a=0;a<Bytes;a++)
{
if(Bytes < count) {*Buffer++ = mmc_read_byte();}
else {mmc_read_byte();}
}
//CRC-Byte auslesen
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
return;
}
//############################################################################
//Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte
void mmc_read_part(unsigned long addr,unsigned char *Buffer, uint16_t count)
//############################################################################
{
//Commando 16 zum lesen eines Blocks von der MMC/SD - Karte
unsigned char cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
/*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
addr wird von Blocks zu Bytes umgerechnet danach werden
diese in das Commando eingefügt*/
addr = addr << 9; //addr = addr * 512
cmd[1] = ((addr & 0xFF000000) >>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<Bytes;a++)
{
data <<= 8;
data |= mmc_read_byte();
if(a & 1) {while(ringbuf_put(buffer, data)) {;}}
}
//CRC-Byte auslesen
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
return;
}
//############################################################################
//Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte
void mmc_read_to_ringbuffer(unsigned long addr, ringbuf_t *buffer)
//############################################################################
{
//Commando 16 zum lesen eines Blocks von der MMC/SD - Karte
unsigned char cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
/*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
addr wird von Blocks zu Bytes umgerechnet danach werden
diese in das Commando eingefügt*/
addr = addr << 9; //addr = addr * 512
cmd[1] = ((addr & 0xFF000000) >>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)

14
mmc.h

@ -8,9 +8,13 @@ Copyright (C) 2004 Ulrich Radig
#define _MMC_H_
#include <avr/io.h>
#include <util/delay.h>
#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_

@ -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);
}

@ -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

Loading…
Cancel
Save