From 6068ce0bc3e1c8906c107fa8891f42010cad2fbf Mon Sep 17 00:00:00 2001 From: Paul Goeser Date: Fri, 13 Jan 2012 12:19:39 +0100 Subject: [PATCH 1/3] added makefile, not debugged yet --- .gitignore | 3 + Makefile | 77 ++++++++++++++++++++++++++ TODO | 6 +- avrbuild/countregs.py | 18 ++++++ avrbuild/functionsize.py | 50 +++++++++++++++++ avrbuild/menu_autogen.py | 43 +++++++++++++++ avrbuild/update_header.py | 113 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100755 avrbuild/countregs.py create mode 100755 avrbuild/functionsize.py create mode 100755 avrbuild/menu_autogen.py create mode 100755 avrbuild/update_header.py diff --git a/.gitignore b/.gitignore index 4a5ba44..41d882d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ /*.swp +/*.d +headeredit +/*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0141dd2 --- /dev/null +++ b/Makefile @@ -0,0 +1,77 @@ +CFLAGS += -Wall -Os -I. -mmcu=attiny26 +DEFINES += -DF_CPU=16e6 + +OBJECTS = gg.o mmc.o + +# further optimization: +# this removes dead code and does global linker optimization +#CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax +#CFLAGS += --param inline-call-cost=2 + +COMPILE = avr-gcc $(CFLAGS) $(DEFINES) + +# symbolic targets: +all: firmware.hex + +.c.o: + $(COMPILE) -c $< -o $@ + +.S.o: + $(COMPILE) -x assembler-with-cpp -c $< -o $@ +# "-x assembler-with-cpp" should not be necessary since this is the default +# file type for the .S (with capital S) extension. However, upper case +# characters are not always preserved on Windows. To ensure WinAVR +# compatibility define the file type manually. + +.c.s: + $(COMPILE) -S $< -o $@ + +flash: all + avrdude -c usbasp -p t26 -U flash:w:firmware.hex + +fuses: + echo TODO +# avrdude -c usbasp -p t26 -U lfuse:w:0xe4:m -U hfuse:w:0xd9:m # internal 8Mhz oscillator + + +## what are the source dependencies +%.d: %.c + @set -e; rm -f $@; \ + $(COMPILE) -MM $< | sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' > $@; +# line 1: exits if anything goes wrong +# line 2a: gcc -MM outputs dependencies +# line 2b: insert the %.d into dependency list + +#main.c: version.h + + +version.h: .svn/entries + export LANG=POSIX; (svn info 2>/dev/null || echo "Revision: unknown") | awk '/^Revision:/ {print "#define SVNVERSION \"" $$2 "\""};' >version.h + + +clean: + rm -f *.o *.hex *.obj *.i *.s *.d */*.i */*.s */*.o */*.d version.h + +# file targets: +firmware.bin: $(OBJECTS) + $(COMPILE) -o firmware.bin $(OBJECTS) + +firmware.hex: firmware.bin + rm -f firmware.hex firmware.eep.hex + avr-objcopy -j .text -j .data -O ihex firmware.bin firmware.hex + avr-size firmware.bin +# ./checksize firmware.bin 8192 960 +# do the checksize script as our last action to allow successful compilation +# on Windows with WinAVR where the Unix commands will fail. + +disasm: firmware.bin + avr-objdump -d firmware.bin >disasm + +functionsize: disasm + python avrbuild/functionsize.py + +countregs: disasm + python avrbuild/countregs.py + +# for depends: +-include $(OBJECTS:.o=.d) diff --git a/TODO b/TODO index bbb4715..ba1137c 100644 --- a/TODO +++ b/TODO @@ -2,10 +2,14 @@ - gehäuse finden - programmieren - - a-law + - sdcard - pwm - drumherum +- testen + - sdcard + - verstärker + - löten - microcontroller - verstärker diff --git a/avrbuild/countregs.py b/avrbuild/countregs.py new file mode 100755 index 0000000..5c50b63 --- /dev/null +++ b/avrbuild/countregs.py @@ -0,0 +1,18 @@ +#!/usr/bin/python +import re +import os + +fd = os.popen("avr-objdump -d firmware.bin") +regcount = [0]*32 +s="foo" +while s: + s=fd.readline() + m=re.findall(r"[ \n\t,;]r(\d\d?)[ \n\t,;]",s) + if m: + for i in m: + regcount[int(i)] += 1; + +for i in range(16): + print "r%2d: %4d"%(i,regcount[i]), + print "\tr%2d: %4d"%(i+16,regcount[i+16]) + diff --git a/avrbuild/functionsize.py b/avrbuild/functionsize.py new file mode 100755 index 0000000..97e6baf --- /dev/null +++ b/avrbuild/functionsize.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +import re +import os + + +def main(): + fd = os.popen("avr-objdump -d firmware.bin") + oldaddr=0 + lastfnname="" + namespacedict = {} + s="foo" + while s: + s=fd.readline() + m=re.match("([0-9a-f]+) <(\w+)>:",s) + if m: + addr,fname=m.groups() + addr=int(addr,16) + size=addr-oldaddr + oldaddr=addr + # print size,"\t",lastfnname + namespace=get_namespace(lastfnname) + try: + namespacedict[namespace].append((lastfnname, size)) + except: + namespacedict[namespace] = [(lastfnname, size)] + lastfnname = fname + + print "individual sizes:" + for k,v in namespacedict.items(): + for a,b in sorted(v): + print "%4i %s"%(b,a) + print "namespace sizes:" + for k,v in namespacedict.items(): + totalsize = sum( [ i[1] for i in v ] ) + print "%4i %s*"%(totalsize,k) + +def get_namespace(name): + matchlist = [ + r"(^__)", + r"(^\w+?_)", + r"(\w[a-z0-9])[A-Z]"] + for i in matchlist: + m = re.match(i, name) + if m: + return m.groups()[0] + return "" + + +if __name__=="__main__": + main() diff --git a/avrbuild/menu_autogen.py b/avrbuild/menu_autogen.py new file mode 100755 index 0000000..e3362b8 --- /dev/null +++ b/avrbuild/menu_autogen.py @@ -0,0 +1,43 @@ +#!/usr/bin/python + +import re + +print "Auto-generating menu_autogen.h..." + +items=set([]) + +fd=file("menu.c") +for line in fd: + m = re.search(r"menu_item_(\w+)\s*\(",line) + if m: + items.add( m.groups()[0]) + +fd.close() + +items=list(items) # create clear ordering + +fd=file("menu_autogen.h","wb") + +fd.write("\n"); +for i in range(len(items)): + fd.write("extern int8_t menu_item_%s();\n" % items[i]) + +fd.write("\ntypedef int8_t (*item_handler_t)();\n\n") + +fd.write("item_handler_t menu_item_handlers[] = {\n") +fd.write("\t\tNULL") + +for i in range(len(items)): + fd.write(",\n\t\t*menu_item_%s" % items[i]) + +fd.write("\n};\n\n") + +for i in range(len(items)): + fd.write("#define MENU_ITEM_%s \t%s\n" % (items[i].upper(), i+1)) + +fd.write("\n") +fd.write("#define MENU_MAX_ITEM %s\n\n"%len(items)) + + + + diff --git a/avrbuild/update_header.py b/avrbuild/update_header.py new file mode 100755 index 0000000..5b17d3b --- /dev/null +++ b/avrbuild/update_header.py @@ -0,0 +1,113 @@ +#!/usr/bin/python + +import re +from sys import argv + +startline = "/* autogenerated by update_header.py. Please check and uncomment.\n" +changedline = "// changed declarations:\n" +newline = "// new declarations:\n" +endline = "*/ // update_header.py end\n" + +def parse_c(data): + l=0 + while l!=len(data): + l=len(data) + data=re.sub(r"(?ms)\{[^{}]*\}",";",data) + data = re.sub(r"(?ms)/\*.*?\*/","",data) + data = re.sub(r"(?m)^#.*$","",data) + data = data.split(";") + data = map(lambda x:x.strip(), data) + data = filter(None, data) # kill empty lines + data = map(lambda x:re.sub(r"\s*=.*$","",x), data) + return data + + +def make_symtable(data): + symbols={} + for i in data: + symname=get_symname(i) + symbols[symname] = i + return symbols + +def get_symname(line): + try: + r = re.search(r"(\w+)($|\(|\[)",line).groups()[0] + return r + except: + raise 'Could not extract symbol from "%s".'%repr(line) + +def update_header(filebase): + data = file(filebase+".c").read() + data = parse_c(data) + header = file(filebase+".h").read() + header = parse_c(header) + headersyms = make_symtable(header) + + changed=[] + new=[] + for i in data: + symname = get_symname(i) + if symname not in headersyms: + new.append(i) + continue + headerline = headersyms[symname] + headerline = re.sub(r"extern\s+","",headerline) + if headerline != i: + changed.append(i) + + print changed + print new + + if (not changed) and (not new): + return # nothing to do + + fd=file(filebase+".h") + header = fd.readlines() + fd.close() + if startline in header: + try: + print "foo" + start=header.index(startline) + stop=header.index(endline) + print start, stop + header = header[:start] + header[stop+1:] + fd = file(filebase+".h","wb") + fd.write("".join(header)) + fd.close() + except: + print "Error killing old entry" + fd = file(filebase+".h","ab") + + fd.write("\n\n\n") + fd.write(startline) + if changed: + fd.write("\n") + fd.write(changedline) + for i in changed: + fd.write("extern "+i+";\n") + if new: + fd.write("\n") + fd.write(newline) + for i in new: + fd.write("extern "+i+";\n") + fd.write("\n") + fd.write(endline) + fd.write("\n\n\n") + fd.close() + + + + + + + + + +def main(): + for i in argv[1:]: + i=re.sub(".[ch]$","",i) + update_header(i) + + +if __name__=="__main__": + main() From 0f4c42b594895b363f239d6f86264f0c2c32bfc2 Mon Sep 17 00:00:00 2001 From: Paul Goeser Date: Fri, 13 Jan 2012 12:49:55 +0100 Subject: [PATCH 2/3] made it compile --- .gitignore | 3 +++ Makefile | 2 +- gg.c | 48 +++++++++---------------------------------- mmc.h | 13 ++++++++++-- other_architectures.c | 33 +++++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 41 deletions(-) create mode 100644 other_architectures.c diff --git a/.gitignore b/.gitignore index 41d882d..17302c2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ /*.d headeredit /*.o +/disasm +/firmware.bin +/firmware.hex diff --git a/Makefile b/Makefile index 0141dd2..b874eeb 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS += -Wall -Os -I. -mmcu=attiny26 +CFLAGS += -Wall -Os -I. -mmcu=attiny26 -std=c99 DEFINES += -DF_CPU=16e6 OBJECTS = gg.o mmc.o diff --git a/gg.c b/gg.c index 624c0b5..dbcb2a2 100644 --- a/gg.c +++ b/gg.c @@ -1,44 +1,14 @@ #include +#include +#include #include "mmc.h" -void timer_init_mega16(void) -{ - ICR1 = (1 << 11) - 1;/* 11 bit pwm */ - OCR1A = 0; - TCCR1A = (1 << COM1A1) | (1 << CS10) | (1 << WGM11);/* fast pwm, non inverted, top in ICR1 */ - TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10);/* fast pwm, top in ICR1, */ - DDRD |= (1 << PD5);/* set pwm pin as output */ - TIMSK = 1 << TOIE1;/* interrupt at top */ -} - -void timer_init_tiny45(void) -{ - PLLCSR = 1 << PLLE;/* pll enable */ - delay_us(100); - while(!(PLLCSR & (1 << PLOCK))) {;}/* wait for lock */ - PLLCSR |= 1 << PCKE;/* use pll */ - - OCR1C = 0xff; - - /* output pin: OC1A = PB1 = 6 */ - OCR1A = 0; - TCCR1 = (1 << PWM1A) | (1 << COM1A1) | (1 << CS10);/* pwm enable, non inverted, no prescaler */ - DDRB |= (1 << PB1); - - /* output pin: OC1B = PB5 = 3 */ - //OCR1B = 0; - //TCCR1 = (1 << CS10);/* no prescaler */ - //GTCCR = (1 << PWM1B) | (1 << COM1B1);/* pwm enable, non inverted */ - //DDRB |= (1 << PB5); - - TIMSK = 1 << TOIE1;/* interrupt on overflow */ -} void timer_init_tiny26(void) { PLLCSR = 1 << PLLE;/* pll enable */ - delay_us(100); + _delay_us(100); while(!(PLLCSR & (1 << PLOCK))) {;}/* wait for lock */ PLLCSR |= 1 << PCKE;/* use pll */ @@ -46,7 +16,7 @@ void timer_init_tiny26(void) /* output pin: OC1A = PB1 = 1 or OC1B = PB3 = 2 */ OCR1A = 0; - TCCR1A = (1 << COM1A1) (1 << PWM1A);/* pwm enable, not inverted */ + TCCR1A = (1 << COM1A1) | (1 << PWM1A);/* pwm enable, not inverted */ TCCR1B = (1 << CS10);/* fast pwm, no prescaler */ DDRB |= (1 << PB1); @@ -55,7 +25,7 @@ void timer_init_tiny26(void) uint8_t length[4];/* remaining samples */ -uint8_t mmc_position[4];/* current reading position on mmc */ +uint32_t mmc_position;/* current reading position on mmc */ uint8_t overflows = 1;/* remaining counter overflows until next sample */ #define SAMPLE_BITS 11 @@ -68,7 +38,7 @@ 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 */ -timerinterrupt() +ISR(TIMER1_OVF1_vect) { //if(!(TIFR & (1 << TOV1))) {continue;}/* interrupt flag polling */ //TIFR |= (1 << TOV1);/* done by hardware */ @@ -87,8 +57,10 @@ timerinterrupt() -void main(void) +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(); @@ -97,7 +69,7 @@ void main(void) { if(pos == refresh_buffer)/* refresh buffer if running low */ { - mmc_read(mmc_position, buffer + (ref + REFRESH_SIZE) % BUFFER_SIZE, BUFFER_SIZE - ref, buffer, REFRESH_AMOUNT - (BUFFER_SIZE - ref)); + 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; } diff --git a/mmc.h b/mmc.h index d23fb0b..0354b5b 100755 --- a/mmc.h +++ b/mmc.h @@ -9,8 +9,8 @@ Copyright (C) 2004 Ulrich Radig #include -#define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI -//#define SPI_Mode 0 +//#define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI +#define SPI_Mode 0 #define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI #define MMC_Read PINB @@ -40,6 +40,15 @@ Copyright (C) 2004 Ulrich Radig #define SPI_SS 4 //Nicht Benutz muß aber definiert werden #endif +#if defined (__AVR_ATtiny26__) + #define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist + #define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist + #define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) + #define MMC_Chip_Select 1 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist + #define SPI_SS 4 //Nicht benutzt, muß aber definiert werden +#endif + + //Prototypes extern unsigned char mmc_read_byte(void); diff --git a/other_architectures.c b/other_architectures.c new file mode 100644 index 0000000..8c30a9f --- /dev/null +++ b/other_architectures.c @@ -0,0 +1,33 @@ + +void timer_init_mega16(void) +{ + ICR1 = (1 << 11) - 1;/* 11 bit pwm */ + OCR1A = 0; + TCCR1A = (1 << COM1A1) | (1 << CS10) | (1 << WGM11);/* fast pwm, non inverted, top in ICR1 */ + TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10);/* fast pwm, top in ICR1, */ + DDRD |= (1 << PD5);/* set pwm pin as output */ + TIMSK = 1 << TOIE1;/* interrupt at top */ +} + +void timer_init_tiny45(void) +{ + PLLCSR = 1 << PLLE;/* pll enable */ + delay_us(100); + while(!(PLLCSR & (1 << PLOCK))) {;}/* wait for lock */ + PLLCSR |= 1 << PCKE;/* use pll */ + + OCR1C = 0xff; + + /* output pin: OC1A = PB1 = 6 */ + OCR1A = 0; + TCCR1 = (1 << PWM1A) | (1 << COM1A1) | (1 << CS10);/* pwm enable, non inverted, no prescaler */ + DDRB |= (1 << PB1); + + /* output pin: OC1B = PB5 = 3 */ + //OCR1B = 0; + //TCCR1 = (1 << CS10);/* no prescaler */ + //GTCCR = (1 << PWM1B) | (1 << COM1B1);/* pwm enable, non inverted */ + //DDRB |= (1 << PB5); + + TIMSK = 1 << TOIE1;/* interrupt on overflow */ +} From 7566ff1317693293450c62cf5068094ed9f0c892 Mon Sep 17 00:00:00 2001 From: Nidan Date: Fri, 13 Jan 2012 16:26:39 +0100 Subject: [PATCH 3/3] file encoding fixes --- gg.c | 2 +- mmc.c | 648 +++++++++++++++++++++++++++++----------------------------- mmc.h | 162 +++++++-------- 3 files changed, 406 insertions(+), 406 deletions(-) mode change 100755 => 100644 mmc.c mode change 100755 => 100644 mmc.h diff --git a/gg.c b/gg.c index dbcb2a2..9a5ea19 100644 --- a/gg.c +++ b/gg.c @@ -52,7 +52,7 @@ ISR(TIMER1_OVF1_vect) /* TODO: a-law decoding */ /* TODO: 11bit PWM emulation */ - OCR1A = buffer[pos];/* play next sample */ + OCR1A = buffer[pos];/* play sample */ } diff --git a/mmc.c b/mmc.c old mode 100755 new mode 100644 index 9dd2e8f..d31b202 --- a/mmc.c +++ b/mmc.c @@ -1,324 +1,324 @@ -/*####################################################################################### -Connect AVR to MMC/SD - -Copyright (C) 2004 Ulrich Radig - -Bei Fragen und Verbesserungen wendet euch per EMail an - -mail@ulrichradig.de - -oder im Forum meiner Web Page : www.ulrichradig.de - -Dieses Programm ist freie Software. Sie können es unter den Bedingungen der -GNU General Public License, wie von der Free Software Foundation veröffentlicht, -weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder -(nach Ihrer Option) jeder späteren Version. - -Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, -daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, -sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT -FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. - -Sie sollten eine Kopie der GNU General Public License zusammen mit diesem -Programm erhalten haben. -Falls nicht, schreiben Sie an die Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -#######################################################################################*/ - -#include "mmc.h" - -//############################################################################ -//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE) -unsigned char mmc_init () -//############################################################################ -{ - unsigned int Timeout = 0; - - //Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde - MMC_Direction_REG &=~(1< 200) - { - MMC_Disable(); - return(1); //Abbruch bei Commando1 (Return Code1) - } - } - //Sendet Commando CMD1 an MMC/SD-Karte - Timeout = 0; - CMD[0] = 0x41;//Commando 1 - CMD[5] = 0xFF; - while( mmc_write_command (CMD) !=0) - { - if (Timeout++ > 400) - { - MMC_Disable(); - return(2); //Abbruch bei Commando2 (Return Code2) - } - } - #if SPI_Mode - //SPI Bus auf max Geschwindigkeit - SPCR &= ~((1< 500) - { - break; //Abbruch da die MMC/SD-Karte nicht Antwortet - } - } - return(tmp); -} - -//############################################################################ -//Routine zum Empfangen eines Bytes von der MMC-Karte -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 - { - MMC_Write &=~(1< 0) //Lesen des Pegels von MMC_DI - { - Byte |= (1<<(a-1)); - } - else - { - Byte &=~(1<<(a-1)); - } - MMC_Write |=(1<0; a--) //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 ); - - //Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes) - tmp = mmc_write_command (cmd); - if (tmp != 0) - { - return(tmp); - } - - //Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte - for (unsigned char a=0;a<100;a++) - { - mmc_read_byte(); - } - - //Sendet Start Byte an MMC/SD-Karte - mmc_write_byte(0xFE); - - //Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte - for (unsigned int a=0;a<512;a++) - { - mmc_write_byte(*Buffer++); - } - - //CRC-Byte schreiben - mmc_write_byte(0xFF); //Schreibt Dummy CRC - mmc_write_byte(0xFF); //CRC Code wird nicht benutzt - - //Fehler beim schreiben? (Data Response XXX00101 = OK) - if((mmc_read_byte()&0x1F) != 0x05) return(1); - - //Wartet auf MMC/SD-Karte Bussy - while (mmc_read_byte() != 0xff){}; - - //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) - MMC_Disable(); - -return(0); -} - -//############################################################################ -//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) -void mmc_read_block(unsigned char *cmd,unsigned char *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){}; - - //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(cmd,Buffer,512); - - return(0); -} - -//############################################################################ -//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) -unsigned char mmc_read_cid (unsigned char *Buffer) -//############################################################################ -{ - //Commando zum lesen des CID Registers - unsigned char cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF}; - - mmc_read_block(cmd,Buffer,16); - - return(0); -} - -//############################################################################ -//Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes) -unsigned char mmc_read_csd (unsigned char *Buffer) -//############################################################################ -{ - //Commando zum lesen des CSD Registers - unsigned char cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF}; - - mmc_read_block(cmd,Buffer,16); - - return(0); -} +/*####################################################################################### +Connect AVR to MMC/SD + +Copyright (C) 2004 Ulrich Radig + +Bei Fragen und Verbesserungen wendet euch per EMail an + +mail@ulrichradig.de + +oder im Forum meiner Web Page : www.ulrichradig.de + +Dieses Programm ist freie Software. Sie können es unter den Bedingungen der +GNU General Public License, wie von der Free Software Foundation veröffentlicht, +weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder +(nach Ihrer Option) jeder späteren Version. + +Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, +dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, +sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT +FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. + +Sie sollten eine Kopie der GNU General Public License zusammen mit diesem +Programm erhalten haben. +Falls nicht, schreiben Sie an die Free Software Foundation, +Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +#######################################################################################*/ + +#include "mmc.h" + +//############################################################################ +//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE) +unsigned char mmc_init () +//############################################################################ +{ + unsigned int Timeout = 0; + + //Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde + MMC_Direction_REG &=~(1< 200) + { + MMC_Disable(); + return(1); //Abbruch bei Commando1 (Return Code1) + } + } + //Sendet Commando CMD1 an MMC/SD-Karte + Timeout = 0; + CMD[0] = 0x41;//Commando 1 + CMD[5] = 0xFF; + while( mmc_write_command (CMD) !=0) + { + if (Timeout++ > 400) + { + MMC_Disable(); + return(2); //Abbruch bei Commando2 (Return Code2) + } + } + #if SPI_Mode + //SPI Bus auf max Geschwindigkeit + SPCR &= ~((1< 500) + { + break; //Abbruch da die MMC/SD-Karte nicht Antwortet + } + } + return(tmp); +} + +//############################################################################ +//Routine zum Empfangen eines Bytes von der MMC-Karte +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 + { + MMC_Write &=~(1< 0) //Lesen des Pegels von MMC_DI + { + Byte |= (1<<(a-1)); + } + else + { + Byte &=~(1<<(a-1)); + } + MMC_Write |=(1<0; a--) //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 ); + + //Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes) + tmp = mmc_write_command (cmd); + if (tmp != 0) + { + return(tmp); + } + + //Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte + for (unsigned char a=0;a<100;a++) + { + mmc_read_byte(); + } + + //Sendet Start Byte an MMC/SD-Karte + mmc_write_byte(0xFE); + + //Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte + for (unsigned int a=0;a<512;a++) + { + mmc_write_byte(*Buffer++); + } + + //CRC-Byte schreiben + mmc_write_byte(0xFF); //Schreibt Dummy CRC + mmc_write_byte(0xFF); //CRC Code wird nicht benutzt + + //Fehler beim schreiben? (Data Response XXX00101 = OK) + if((mmc_read_byte()&0x1F) != 0x05) return(1); + + //Wartet auf MMC/SD-Karte Bussy + while (mmc_read_byte() != 0xff){}; + + //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) + MMC_Disable(); + +return(0); +} + +//############################################################################ +//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) +void mmc_read_block(unsigned char *cmd,unsigned char *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){}; + + //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(cmd,Buffer,512); + + return(0); +} + +//############################################################################ +//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) +unsigned char mmc_read_cid (unsigned char *Buffer) +//############################################################################ +{ + //Commando zum lesen des CID Registers + unsigned char cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF}; + + mmc_read_block(cmd,Buffer,16); + + return(0); +} + +//############################################################################ +//Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes) +unsigned char mmc_read_csd (unsigned char *Buffer) +//############################################################################ +{ + //Commando zum lesen des CSD Registers + unsigned char cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF}; + + mmc_read_block(cmd,Buffer,16); + + return(0); +} diff --git a/mmc.h b/mmc.h old mode 100755 new mode 100644 index 0354b5b..11dd25a --- a/mmc.h +++ b/mmc.h @@ -1,81 +1,81 @@ -/*####################################################################################### -Connect ARM to MMC/SD - -Copyright (C) 2004 Ulrich Radig -#######################################################################################*/ - -#ifndef _MMC_H_ - #define _MMC_H_ - -#include - -//#define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI -#define SPI_Mode 0 - -#define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI -#define MMC_Read PINB -#define MMC_Direction_REG DDRB - -#if defined (__AVR_ATmega128__) - #define SPI_DI 3 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist - #define SPI_DO 2 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist - #define SPI_Clock 1 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) - #define MMC_Chip_Select 4 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist - #define SPI_SS 0 //Nicht Benutz muß aber definiert werden -#endif - -#if defined (__AVR_ATmega32__) - #define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist - #define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist - #define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) - #define MMC_Chip_Select 3 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist - #define SPI_SS 4 //Nicht Benutz muß aber definiert werden -#endif - -#if defined (__AVR_ATmega644__) - #define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist - #define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist - #define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) - #define MMC_Chip_Select 1 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist - #define SPI_SS 4 //Nicht Benutz muß aber definiert werden -#endif - -#if defined (__AVR_ATtiny26__) - #define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist - #define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist - #define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) - #define MMC_Chip_Select 1 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist - #define SPI_SS 4 //Nicht benutzt, muß aber definiert werden -#endif - - -//Prototypes -extern unsigned char mmc_read_byte(void); - -extern void mmc_write_byte(unsigned char); - -extern void mmc_read_block(unsigned char *,unsigned char *,unsigned in); - -extern unsigned char mmc_init(void); - -extern unsigned char mmc_read_sector (unsigned long,unsigned char *); - -extern unsigned char mmc_write_sector (unsigned long,unsigned char *); - -extern unsigned char mmc_write_command (unsigned char *); - -extern unsigned char mmc_read_csd (unsigned char *); - -extern unsigned char mmc_read_cid (unsigned char *); - -//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) -#define MMC_Disable() MMC_Write|= (1< + +//#define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI +#define SPI_Mode 0 + +#define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI +#define MMC_Read PINB +#define MMC_Direction_REG DDRB + +#if defined (__AVR_ATmega128__) + #define SPI_DI 3 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist + #define SPI_DO 2 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist + #define SPI_Clock 1 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) + #define MMC_Chip_Select 4 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist + #define SPI_SS 0 //Nicht Benutz muss aber definiert werden +#endif + +#if defined (__AVR_ATmega32__) + #define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist + #define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist + #define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) + #define MMC_Chip_Select 3 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist + #define SPI_SS 4 //Nicht Benutz muss aber definiert werden +#endif + +#if defined (__AVR_ATmega644__) + #define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist + #define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist + #define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) + #define MMC_Chip_Select 1 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist + #define SPI_SS 4 //Nicht Benutz muss aber definiert werden +#endif + +#if defined (__AVR_ATtiny26__) + #define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist + #define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist + #define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk) + #define MMC_Chip_Select 1 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist + #define SPI_SS 4 //Nicht benutzt, muss aber definiert werden +#endif + + +//Prototypes +extern unsigned char mmc_read_byte(void); + +extern void mmc_write_byte(unsigned char); + +extern void mmc_read_block(unsigned char *,unsigned char *,unsigned in); + +extern unsigned char mmc_init(void); + +extern unsigned char mmc_read_sector (unsigned long,unsigned char *); + +extern unsigned char mmc_write_sector (unsigned long,unsigned char *); + +extern unsigned char mmc_write_command (unsigned char *); + +extern unsigned char mmc_read_csd (unsigned char *); + +extern unsigned char mmc_read_cid (unsigned char *); + +//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) +#define MMC_Disable() MMC_Write|= (1<