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()