From ce87f3b8f593252cca98dbc768cf564442d08a7b Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Wed, 3 Aug 2011 16:34:09 +0200 Subject: [PATCH] New loadable style with big dispatcher table. --- firmware/Makefile | 7 + firmware/l0dable/.gitignore | 4 + firmware/l0dable/EXPORTS | 37 ++++++ firmware/l0dable/Makefile | 55 ++++++++ firmware/l0dable/blink.c | 12 ++ firmware/l0dable/debug.c | 230 +++++++++++++++++++++++++++++++++ firmware/l0dable/loadable.ld | 5 + firmware/l0dable/mandel.c | 173 +++++++++++++++++++++++++ firmware/l0dable/mktable.pl | 105 +++++++++++++++ firmware/l0dable/ram.ld | 48 +++++++ firmware/lpc1xxx/linkscript.ld | 1 + 11 files changed, 677 insertions(+) create mode 100644 firmware/l0dable/.gitignore create mode 100644 firmware/l0dable/EXPORTS create mode 100644 firmware/l0dable/Makefile create mode 100644 firmware/l0dable/blink.c create mode 100644 firmware/l0dable/debug.c create mode 100644 firmware/l0dable/loadable.ld create mode 100644 firmware/l0dable/mandel.c create mode 100755 firmware/l0dable/mktable.pl create mode 100644 firmware/l0dable/ram.ld diff --git a/firmware/Makefile b/firmware/Makefile index 9f1b1f7..732c824 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -9,6 +9,10 @@ LIBS = VPATH += OBJS += main.o +ifeq "$(wildcard table.c)" "table.c" +OBJS += table.o +endif + LIBS += lcd/liblcd.a LIBS += basic/libbasic.a LIBS += core/libcore.a @@ -61,6 +65,9 @@ protect: $(OUTFILE).bin loadables: $(OUTFILE).bin @cd loadable && $(MAKE) +l0dables: + @cd l0dable && $(MAKE) + clean: rm -f $(OBJS) $(LD_TEMP) $(OUTFILE).elf $(OUTFILE).bin $(OUTFILE).hex for dir in $(SUBDIRS); do \ diff --git a/firmware/l0dable/.gitignore b/firmware/l0dable/.gitignore new file mode 100644 index 0000000..7652361 --- /dev/null +++ b/firmware/l0dable/.gitignore @@ -0,0 +1,4 @@ +*.elf +*.bin +*.h +loadable.ld diff --git a/firmware/l0dable/EXPORTS b/firmware/l0dable/EXPORTS new file mode 100644 index 0000000..05a3962 --- /dev/null +++ b/firmware/l0dable/EXPORTS @@ -0,0 +1,37 @@ +DoInt +DoIntX +DoString +GetLight +GetUUID32 +GetVoltage +IntToStr +IntToStrX +_timectr +delayms +delayms_queue +getInputRaw +getInputWaitRelease +getSeconds +gpioGetValue +gpioSetValue +handleMenu +iapReadSerialNumber +isNight +lcdClear +lcdDisplay +lcdNl +lcdPrint +lcdPrintInt +lcdPrintIntHex +lcdPrintln +lcdRefresh +lcdSetPixel +lcdShift +meshbuffer +meshgen +meshincctr +mygmtime +push_queue +the_config +the_queue +work_queue diff --git a/firmware/l0dable/Makefile b/firmware/l0dable/Makefile new file mode 100644 index 0000000..f4f6714 --- /dev/null +++ b/firmware/l0dable/Makefile @@ -0,0 +1,55 @@ +########################################################################## +# User configuration and firmware specific object files +########################################################################## +SRCS = $(wildcard *.c) +OBJS = $(foreach mod,$(SRCS),$(subst .c,.o,$(mod))) +ELFS = $(foreach mod,$(SRCS),$(subst .c,.elf,$(mod))) +BINS = $(foreach mod,$(SRCS),$(subst .c,.bin,$(mod))) + +########################################################################## +# GNU GCC compiler flags +########################################################################## +ROOT_PATH?= .. + +INCLUDE_PATHS = -I$(ROOT_PATH) -I$(ROOT_PATH)/core + +include $(ROOT_PATH)/Makefile.inc + +########################################################################## +# Compiler settings, parameters and flags +########################################################################## +LDSRCFILE=ram.ld +LDFILE=loadable.ld +CFLAGS+=-mlong-calls -fno-toplevel-reorder + +all: $(OBJS) $(ELFS) $(BINS) + +$(LDFILE): + -@echo "MEMORY" > $(LDFILE) + -@echo "{" >> $(LDFILE) + -@echo " sram(rwx): ORIGIN = 0x10002000 - $(RAMCODE), LENGTH = $(RAMCODE)" >> $(LDFILE) + -@echo "}" >> $(LDFILE) + -@echo "INCLUDE $(LDSRCFILE)" >> $(LDFILE) + +%.o : %.c + $(CC) $(CFLAGS) -o $@ $< + +%.elf: %.o $(FIRMWARE) $(LDFILE) + $(LD) $(LDFLAGS) -T $(LDFILE) -o $@ $< + $(SIZE) $@ + +%.bin: %.elf + $(OBJCOPY) $(OCFLAGS) -O binary $< $@ + +clean: + rm -f *.o *.elf *.bin + +IDIR=/cygdrive/f +install: + for a in $(BINS) ; do f=$${a#*/};cp $$a $(IDIR)/$${f%.bin}.c0d ; done + +$(OBJS): usetable.h + +.SUFFIXES: + +.PHONY: $(LDFILE) diff --git a/firmware/l0dable/blink.c b/firmware/l0dable/blink.c new file mode 100644 index 0000000..06ae4e7 --- /dev/null +++ b/firmware/l0dable/blink.c @@ -0,0 +1,12 @@ +#include + +#include "basic/basic.h" + +#include "usetable.h" + +void ram(void){ + for (int x=0;x<20;x++){ + gpioSetValue (RB_LED1, x%2); + delayms(50); + }; +}; diff --git a/firmware/l0dable/debug.c b/firmware/l0dable/debug.c new file mode 100644 index 0000000..0ba5381 --- /dev/null +++ b/firmware/l0dable/debug.c @@ -0,0 +1,230 @@ +#include +#include + +#include "basic/basic.h" +#include "basic/config.h" + +#include "lcd/render.h" +#include "lcd/print.h" + +#include "usb/usbmsc.h" + +#include "core/iap/iap.h" + +#include "funk/mesh.h" + +#include "usetable.h" + +/**************************************************************************/ +void ChkFlame(void); +void ChkLight(void); +void ChkBattery(void); +void m_time(void); +void Qstatus(void); +void getsp(void); +void uptime(void); +void uuid(void); + +static const struct MENU submenu_debug={ "debug", { + { "ChkBattery", &ChkBattery}, +// { "ChkFlame", &ChkFlame}, + { "ChkLight", &ChkLight}, + { "MeshInfo", &m_time}, + { "Qstatus", &Qstatus}, + { "ShowSP", &getsp}, + { "Uptime", &uptime}, + { "Uuid", &uuid}, + {NULL,NULL} +}}; + +void ram(void) { + handleMenu(&submenu_debug); +}; + +//# MENU debug ChkLight +void ChkLight(void) { + int dx=0; + int dy=8; + dx=DoString(0,dy,"Light:"); + DoString(0,dy+16,"Night:"); + while ((getInputRaw())==BTN_NONE){ + DoInt(dx,dy,GetLight()); + DoInt(dx,dy+16,isNight()); + DoInt(dx,dy+8,GLOBAL(daytrig)); + lcdDisplay(); + delayms_queue(100); + }; + dx=DoString(0,dy+24,"Done."); +} + +//# MENU debug ChkBattery +void ChkBattery(void) { + do{ + lcdClear(); + lcdPrintln("Voltage:"); + lcdPrintln(IntToStr(GetVoltage(),5,0)); + lcdNl(); + lcdPrintln("Chrg_stat:"); + if(gpioGetValue(RB_PWR_CHRG)){ + lcdPrintln("1"); + }else{ + lcdPrintln("0"); + }; + lcdRefresh(); + delayms_queue(100); + } while ((getInputRaw())==BTN_NONE); +} + +//# MENU debug Uptime +void uptime(void) { + int t; + int h; + char flag; + while ((getInputRaw())==BTN_NONE){ + lcdClear(); + lcdPrintln("Uptime:"); + t=(_timectr)/(1000/SYSTICKSPEED); + h=t/60/60; + flag=F_ZEROS; + if(h>0){ + lcdPrint(IntToStr(h,2,flag)); + lcdPrint("h"); + flag|=F_LONG; + }; + h=t/60%60; + if(h>0){ + lcdPrint(IntToStr(h,2,flag)); + lcdPrint("m"); + flag|=F_LONG; + }; + h=t%60; + if(h>0){ + lcdPrint(IntToStr(h,2,flag)); + lcdPrint("s"); + }; + lcdNl(); + lcdNl(); + lcdPrintln("Ticks:"); + lcdPrint(IntToStr(_timectr,10,0)); + lcdRefresh(); + delayms_queue(222); + }; + lcdPrintln("done."); +} + +//# MENU debug Uuid +void uuid(void) { + IAP_return_t iap_return; + iap_return = iapReadSerialNumber(); + lcdClear(); + lcdPrintln("UUID:"); + lcdPrintIntHex(iap_return.Result[0]); lcdNl(); + lcdPrintIntHex(iap_return.Result[1]); lcdNl(); + lcdPrintIntHex(iap_return.Result[2]); lcdNl(); + lcdPrintIntHex(iap_return.Result[3]); lcdNl(); + lcdNl(); + lcdPrintln("Beacon ID:"); + lcdPrintln(IntToStrX(GetUUID32(),4)); + lcdRefresh(); +} + +//# MENU debug Qstatus +void Qstatus(void) { + int dx=0; + int dy=8; + lcdClear(); + dx=DoString(0,dy+16,"Qdepth:"); + while ((getInputRaw())!=BTN_ENTER){ + DoInt(dx,dy+16,(the_queue.qend-the_queue.qstart+MAXQENTRIES)%MAXQENTRIES); + lcdDisplay(); + if(getInputRaw()!=BTN_NONE) + work_queue(); + else + delayms(10); + }; + dy+=16; + dx=DoString(0,dy,"Done."); +}; + +void blink_led0(void){ + gpioSetValue (RB_LED0, 1-gpioGetValue(RB_LED0)); +}; + +void tick_alive(void){ + static int foo=0; + + if(GLOBAL(alivechk)==0) + return; + + if(foo++>500/SYSTICKSPEED){ + foo=0; + if(GLOBAL(alivechk)==2) + push_queue(blink_led0); + else + blink_led0(); + }; + return; +}; + +//# MENU debug ShowSP +void getsp(void) { + int dx=0; + int dy=8; + int x; + lcdClear(); + dx=DoString(0,dy,"SP:"); + while ((getInputRaw())==BTN_NONE){ + __asm( "mov %0, sp\n" : "=r" (x) :); + DoIntX(0,dy+8,x); + lcdDisplay(); + delayms_queue(50); + }; + dy+=16; + dx=DoString(0,dy,"Done."); +}; + +void m_time(void){ + struct tm* tm; + char c[2]={0,0}; + getInputWaitRelease(); + delayms(100); + do{ + lcdClear(); + tm= mygmtime(getSeconds()); + lcdPrint(IntToStr(tm->tm_hour,2,F_LONG)); + lcdPrint(":"); + lcdPrint(IntToStr(tm->tm_min,2,F_LONG|F_ZEROS)); + lcdPrint(":"); + lcdPrint(IntToStr(tm->tm_sec,2,F_LONG|F_ZEROS)); + lcdNl(); + lcdPrint(IntToStr(tm->tm_mday,2,F_LONG)); + lcdPrint("."); + lcdPrint(IntToStr(tm->tm_mon+1,2,0)); + lcdPrint("."); + lcdPrint(IntToStr(tm->tm_year+YEAR0,4,F_LONG|F_ZEROS)); + lcdNl(); + + lcdNl(); + lcdPrint("<"); + + for(int i=0;i"); + + lcdPrint("Gen:"); + lcdPrintInt(meshgen); + lcdNl(); + lcdPrint("Inc:"); + lcdPrintInt(meshincctr); + lcdNl(); + lcdRefresh(); + delayms_queue(50); + }while ((getInputRaw())==BTN_NONE); +}; + diff --git a/firmware/l0dable/loadable.ld b/firmware/l0dable/loadable.ld new file mode 100644 index 0000000..fb4d66c --- /dev/null +++ b/firmware/l0dable/loadable.ld @@ -0,0 +1,5 @@ +MEMORY +{ + sram(rwx): ORIGIN = 0x10002000 - 2048, LENGTH = 2048 +} +INCLUDE ram.ld diff --git a/firmware/l0dable/mandel.c b/firmware/l0dable/mandel.c new file mode 100644 index 0000000..d00503a --- /dev/null +++ b/firmware/l0dable/mandel.c @@ -0,0 +1,173 @@ +#include + +#include "basic/basic.h" + +#include "lcd/render.h" +#include "lcd/display.h" +#include "lcd/allfonts.h" + +#include "usetable.h" + +#define FIXSIZE 25 +#define mul(a,b) ((((long long)a)*(b))>>FIXSIZE) +#define fixpt(a) ((long)(((a)*(1<>FIXSIZE) + +#define ZOOM_RATIO 0.90 +#define ITERATION_MAX 150 + +void mandelInit(); +void mandelMove(); +void mandelUpdate(); + +void ram(void) { + int key; + mandelInit(); + while (1) { + lcdDisplay(); + mandelMove(); + mandelUpdate(); + + // Exit on enter+direction + key=getInputRaw(); + if(key&BTN_ENTER && key>BTN_ENTER) + return; + } + return; +} + +struct mb { + long rmin, rmax, imin, imax; + bool dirty, dup, ddown, dleft, dright; +} mandel; + +void mandelInit() { + //mandel.rmin = -2.2*0.9; + //mandel.rmax = 1.0*0.9; + //mandel.imin = -2.0*0.9; + //mandel.imax = 2.0*0.9; + mandel.rmin = fixpt(-2); + mandel.rmax = fixpt(1); + mandel.imin = fixpt(-2); + mandel.imax = fixpt(2); + + mandel.dirty = true; + mandel.dup = false; + mandel.ddown = false; + mandel.dleft = false; + mandel.dright = false; +} + +void mandelMove() { + //long delta_r = (mandel.rmax - mandel.rmin)/10; + //long delta_i = (mandel.imax - mandel.imin)/10; + + long rs =(mandel.rmax-mandel.rmin)/RESY; + long is =(mandel.imax-mandel.imin)/RESX; + + char key = getInputRaw(); + + if (key == BTN_LEFT) { + mandel.imax -=is; + mandel.imin -=is; + mandel.dleft = true; + } else if (key == BTN_RIGHT) { + mandel.imax += is; + mandel.imin += is; + mandel.dright = true; + } else if (key == BTN_DOWN) { + mandel.rmax += rs; + mandel.rmin += rs; + mandel.ddown = true; + } else if (key == BTN_UP) { + mandel.rmax -= rs; + mandel.rmin -= rs; + mandel.dup = true; + } else if (key == (BTN_ENTER + BTN_UP)) { + mandel.imin = mandel.imin + (mandel.imax-mandel.imin)/10; + mandel.imax = mandel.imax - (mandel.imax-mandel.imin)/10; + mandel.rmin = mandel.rmin +(mandel.rmax-mandel.rmin)/10; + mandel.rmax = mandel.rmax -(mandel.rmax-mandel.rmin)/10; + mandel.dirty = true; + } else if (key == (BTN_ENTER + BTN_DOWN)) { + mandel.imin = mandel.imin - (mandel.imax-mandel.imin)/10; + mandel.imax = mandel.imax + (mandel.imax-mandel.imin)/10; + mandel.rmin = mandel.rmin -(mandel.rmax-mandel.rmin)/10; + mandel.rmax = mandel.rmax +(mandel.rmax-mandel.rmin)/10; + mandel.dirty = true; + } +} + +void mandelPixel(int x, int y) { + long r0,i0,rn, p,q; + long rs,is; + int iteration; + + rs=(mandel.rmax-mandel.rmin)/RESY; + is=(mandel.imax-mandel.imin)/RESX; + //p=fixpt(mandel.rmin+y*rs); + //q=fixpt(mandel.imin+x*is); + p=mandel.rmin+y*rs; + q=mandel.imin+x*is; + + rn=0; + r0=0; + i0=0; + iteration=0; + while ((mul(rn,rn)+mul(i0,i0))1); + lcdSetPixel(x, y, pixel); +} + +void mandelUpdate() { + int xmin,xmax,ymin,ymax; + if (mandel.dirty) { + xmin = 0; + xmax = RESX; + ymin = 0; + ymax = RESY; + mandel.dirty = false; + } else if (mandel.dleft) { + lcdShift(1,0,false); + xmin = 0; + xmax = 1; + ymin = 0; + ymax = RESY; + mandel.dleft = false; + } else if (mandel.dright) { + lcdShift(-1,0,false); + xmin = RESX-1; + xmax = RESX; + ymin = 0; + ymax = RESY; + mandel.dright = false; + } else if (mandel.dup) { + lcdShift(0,-1,true); + xmin=0; + xmax=RESX; + ymin=0; + ymax=1; + mandel.dup = false; + } else if (mandel.ddown) { + lcdShift(0,1,true); + xmin=0; + xmax=RESX; + ymin=RESY-1; + ymax=RESY; + mandel.ddown = false; + } else { + return; + } + + for (int x = xmin; x){ + chomp;s/\r$//; + push @symb,$_; +}; +close(Q); + +$\="\n"; + +open (C,">","table.c")||die; +print C '#include "table.h"'; + +open (H,">","table.h")||die; +print H "#include "; + +open (I,">","$DIR/usetable.h")||die; +print I "extern const void * TheTable[];"; + +print I ""; + +my %types; +my %files; +my %variable; + +use File::Find (); + +sub wanted { + my $id; + next unless /\.h$/; + open(F,"<",$_) || die; + while(){ + chomp;s/\r$//; + if(m!^[^(]* ([\w]+)\s*\(.*\);\s*(//.*)?$!){ + $id=$1; + s/$id/(*)/; + s/;//; + s!//.*!!; + $types{$id}="*($_)"; + $files{$id}=$File::Find::name; + }elsif (m!^\s*extern\s[^(]* ([\w]+)\s*(\[\w*\]\s*)?;\s*(//.*)?$!){ + $id=$1; + s/extern //; + my $star="*"; + if( s/\[\w*\]//){ + $star=""; + }; + s/$id/*/; + s/;//; + s!//.*!!; + $types{$id}="$star($_)"; + $variable{$id}=1; + $files{$id}=$File::Find::name; + }; + }; + close(F); +} + +File::Find::find({wanted => \&wanted}, '.'); + +print C ""; +print C qq!__attribute__ ((used, section("table"))) const void * TheTable[]={!; + +my %defs; + +for my $idx (0..$#symb){ + $_=$symb[$idx]; + if(!$types{$_}){ + warn "Couldn't find $symb[$idx]"; + }; + if(!$defs{$files{$_}}){ + print H qq!#include "$files{$_}"!; + $defs{$files{$_}}++; + }; + + if($variable{$_}){ + print C "\&$_,"; + }else{ + print C "$_,"; + }; + print I "#define $_ ($types{$_}(TheTable[$idx]))"; +}; + +print C "};"; + +close(I); +close(H); +close(C); + diff --git a/firmware/l0dable/ram.ld b/firmware/l0dable/ram.ld new file mode 100644 index 0000000..bc62075 --- /dev/null +++ b/firmware/l0dable/ram.ld @@ -0,0 +1,48 @@ + +sram_top = ORIGIN(sram) + LENGTH(sram); +TheTable = 0x00000124; +ENTRY(ram) + +SECTIONS +{ + .text : + { + *(.text*) + *(.rodata*) + } > sram + + /* + * More information about Special Section Indexes is available in the + * free "ELF for the ARM Architecture" document from ARM Limited + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf + * + */ + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > sram + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > sram + __exidx_end = .; + + _etext = .; + + .data : AT (__exidx_end) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > sram + + /* zero initialized data */ + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > sram + + end = .; + + /* For GDB compatibility we decrease the top with 16 bytes */ + stack_entry = sram_top - 16; +} diff --git a/firmware/lpc1xxx/linkscript.ld b/firmware/lpc1xxx/linkscript.ld index b6598f6..f8c8086 100644 --- a/firmware/lpc1xxx/linkscript.ld +++ b/firmware/lpc1xxx/linkscript.ld @@ -36,6 +36,7 @@ SECTIONS .text : { KEEP(*(.irq_vectors)) + KEEP(*(table)) *(.text*) *(.rodata*) } > flash