From: dwhuseby Date: Thu, 13 Jan 2011 07:25:50 +0000 (+0000) Subject: A major refactor of the GoodFET firmware build system and apps to give better X-Git-Url: http://git.rot13.org/?p=goodfet;a=commitdiff_plain;h=5fb0341d348e101b30794945a6c91546e25e8e7b;hp=1969a022e69bdac64a0d88de3d0ce88d79a27804 A major refactor of the GoodFET firmware build system and apps to give better encapsulation and separation of code. Each app now has a struct containing meta data and handle fn hooks. The apps.h/.c are now autogenerated as well as a builddate.h containing the build date. The goodfet.monitor client has a new command: goodfet.monitor listapps [full] This walks the global apps list and lists out the apps compiled into the firmware as well as the date it was built. If the "full" option is given, it also prints out the description strings for each app. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@837 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- diff --git a/client/GoodFET.py b/client/GoodFET.py index 98c2494..65fb46c 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -478,6 +478,30 @@ class GoodFET: if self.verbose: print "Comm error recognized by monitorecho()."; return 0; return 1; + + def monitor_info(self): + print "GoodFET with %s MCU" % self.infostring(); + print "Clocked at %s" % self.monitorclocking(); + return 1; + + def monitor_list_apps(self, full=False): + self.monitor_info() + old_value = self.besilent + self.besilent = True # turn off automatic call to readcmd + self.writecmd(self.MONITORAPP, 0x82, 1, [int(full)]); + self.besilent = old_value + + # read the build date string + self.readcmd() + print "Build Date: %s" % self.data + print "Firmware apps:" + while True: + self.readcmd() + if self.count == 0: + break + print self.data + return 1; + def monitorclocking(self): """Return the 16-bit clocking value.""" return "0x%04x" % self.monitorgetclock(); diff --git a/client/GoodFETJTAG.py b/client/GoodFETJTAG.py new file mode 100644 index 0000000..4dc4061 --- /dev/null +++ b/client/GoodFETJTAG.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# GoodFET Basic JTAG Client + +import sys, binascii, struct + +# Standard verbs +READ = 0x00 +WRITE = 0x01 +PEEK = 0x02 +POKE = 0x03 +SETUP = 0x10 +START = 0x20 +STOP = 0x21 +CALL = 0x30 +EXEC = 0x31 +NOK = 0x7E +OK = 0x7F + +from GoodFET import GoodFET +from intelhex import IntelHex + +class GoodFETJTAG(GoodFET): + + """A GoodFET variant for basic JTAG'ing.""" + + JTAGAPP=0x10; + APP=JTAGAPP; + + def setup(self): + """Move the FET into the JTAG configuration.""" + print "Initializing JTAG..." + #self.writecmd(self.APP, SETUP, 0, self.data) + + def detect(self): + """Detect the JTAG IR width.""" + pass + + diff --git a/client/GoodFETXSCALE.py b/client/GoodFETXSCALE.py index 6e0aed5..f71b52e 100644 --- a/client/GoodFETXSCALE.py +++ b/client/GoodFETXSCALE.py @@ -1,11 +1,5 @@ #!/usr/bin/env python -# GoodFET Client Library -# -# -# Good luck with alpha / beta code. -# Contributions and bug reports welcome. -# -# NOTE: this is just a hacked up copy of the GoodFETARM.py file +# GoodFET XScale JTAG Client import sys, binascii, struct @@ -25,14 +19,14 @@ OK = 0x7F # XSCALE JTAG verbs GET_CHIP_ID = 0xF1 -from GoodFET import GoodFET +from GoodFETJTAG import GoodFETJTAG from intelhex import IntelHex -class GoodFETXSCALE(GoodFET): +class GoodFETXSCALE(GoodFETJTAG): """A GoodFET variant for use with XScale processors.""" - XSCALEAPP=0x13; + XSCALEAPP=0x15; APP=XSCALEAPP; def setup(self): diff --git a/client/goodfet.monitor b/client/goodfet.monitor index 6191335..4d54dc2 100755 --- a/client/goodfet.monitor +++ b/client/goodfet.monitor @@ -18,6 +18,7 @@ if(len(sys.argv)==1): print "%s info" % sys.argv[0]; print "%s call 0x$start" % sys.argv[0]; print "%s exec '0x35 0x00 0x..'" % sys.argv[0]; + print "%s listapps [full]" % sys.argv[0] sys.exit(); #Initialize FET and set baud rate @@ -46,8 +47,7 @@ if(sys.argv[1]=="exec"): client.execute(code); if(sys.argv[1]=="info"): - print "GoodFET with %s MCU" % client.infostring(); - print "Clocked at %s" % client.monitorclocking(); + client.monitor_info() if(sys.argv[1]=="clocktest"): print "GoodFET with %s MCU" % client.infostring(); clocking=client.monitorgetclock(); @@ -58,6 +58,9 @@ if(sys.argv[1]=="clocktest"): client.monitorsetclock(clocking-foo); print "-0x%04x: %s" % (foo,client.infostring()); +if(sys.argv[1]=="listapps"): + full = (len(sys.argv) > 2) and (sys.argv[2]=="full") + client.monitor_list_apps(full); if(sys.argv[1]=="ramfill"): client.monitor_ram_pattern(); diff --git a/firmware/Makefile b/firmware/Makefile index f799d6b..42adfc2 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -52,7 +52,7 @@ CC=msp430-gcc -Wall -Os -g -mmcu=$(mcu) -D$(mcu) -D$(platform) -Dplatform=$(plat # Microcontrollers: # chipcon -- Chipcon radio 8051 debugging # avr -- AVR debugger -# dspic -- PIC24H/dsPIC33F debugger +# pic -- PIC24H/dsPIC33F debugger # adc -- ADC10 (still specific to x2274, GoodFET32) # Radios: @@ -62,6 +62,7 @@ CC=msp430-gcc -Wall -Os -g -mmcu=$(mcu) -D$(mcu) -D$(platform) -Dplatform=$(plat # Miscelaneous: # glitch -- Glitch research tool # smartcard -- Smartcard IO +# ps2 -- PS2 spy # Configurations @@ -84,30 +85,35 @@ CC=msp430-gcc -Wall -Os -g -mmcu=$(mcu) -D$(mcu) -D$(platform) -Dplatform=$(plat # config = monitor glitch # XScale PXA255 JTAG -# config = monitor jtagxscale +config = monitor jtagxscale # Old Default Config -config = monitor sbw glitch chipcon nrf ccspi spi jtagarm7 jtag430 jtag430x2 avr +#config = monitor sbw glitch chipcon nrf ccspi spi jtagarm7 jtag430 jtag430x2 avr # Build the needed list of app and lib object files from the config -apps= -libs= lib/$(mcu).o lib/command.o lib/dco_calib.o +apps= +libs= lib/$(mcu).o lib/command.o lib/dco_calib.o lib/apps.o +hdrs= +ERR= # include monitor app ifeq ($(filter monitor, $(config)), monitor) apps+= apps/monitor/monitor.o + hdrs+= monitor.h endif # include spi app ifeq ($(filter spi, $(config)), spi) apps+= apps/spi/spi.o + hdrs+= spi.h endif # include base jtag if they specified it explicitly ifeq ($(filter jtag, $(config)), jtag) ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) apps+= apps/jtag/jtag.o + hdrs+= jtag.h endif endif @@ -116,8 +122,10 @@ ifeq ($(filter sbw, $(config)), sbw) # if they only specify sbw, include jtag ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) apps+= apps/jtag/jtag.o + hdrs+= jtag.h endif apps+= apps/jtag/sbw.o + hdrs+= sbw.h endif # include jtag430 app @@ -125,12 +133,14 @@ ifeq ($(filter jtag430, $(config)), jtag430) # add in base jtag code if not already ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) apps+= apps/jtag/jtag.o + hdrs+= jtag.h endif # add in the jtag430asm code if needed ifneq ($(filter apps/jtag/jtag430asm.o, $(libs)), apps/jtag/jtag430asm.o) apps+= apps/jtag/jtag430asm.o endif apps+= apps/jtag/jtag430.o + hdrs+= jtag430.h endif # include jtag430x2 app @@ -138,17 +148,21 @@ ifeq ($(filter jtag430x2, $(config)), jtag430x2) # add in base jtag code if not already ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) apps+= apps/jtag/jtag.o + hdrs+= jtag.h endif # add in the jtag430asm code if needed ifneq ($(filter jtag430asm.o, $(libs)), jtag430asm.o) libs+= apps/jtag/jtag430asm.o + hdrs+= jtag430.h endif apps+= apps/jtag/jtag430x2.o + hdrs+= jtag430x2.h endif # include i2c app ifeq ($(filter i2c, $(config)), i2c) apps+= apps/i2c/i2c.o + hdrs+= i2c.h endif # include jtagarm7 app @@ -156,26 +170,32 @@ ifeq ($(filter jtagarm7, $(config)), jtagarm7) # add in base jtag code if not already ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) apps+= apps/jtag/jtag.o + hdrs+= jtag.h endif apps+= apps/jtag/jtagarm7.o + hdrs+= jtagarm7.h endif # include jtagarm7tdmi app -ifeq ($(filter jtagarm7tdmi, $(config)), jtagarm7tdmi) +#ifeq ($(filter jtagarm7tdmi, $(config)), jtagarm7tdmi) # add in base jtag code if not already - ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) - apps+= apps/jtag/jtag.o - endif - apps+= apps/jtag/jtagarm7tdmi.o -endif + #ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) + #apps+= apps/jtag/jtag.o + #hdrs+= jtag.h + #endif + #apps+= apps/jtag/jtagarm7tdmi.o + #hdrs+= jtagarm7tdmi.h +#endif # include ejtag app ifeq ($(filter ejtag, $(config)), ejtag) # add in base jtag code if not already ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) apps+= apps/jtag/jtag.o + hdrs+= jtag.h endif apps+= apps/jtag/ejtag.o + hdrs+= ejtag.h endif # include jtagxscale app @@ -183,57 +203,69 @@ ifeq ($(filter jtagxscale, $(config)), jtagxscale) # add in base jtag code if not already ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o) apps+= apps/jtag/jtag.o + hdrs+= jtag.h endif apps+= apps/jtag/jtagxscale.o + hdrs+= jtagxscale.h endif # include chipcon app ifeq ($(filter chipcon, $(config)), chipcon) apps+= apps/chipcon/chipcon.o + hdrs+= chipcon.h endif # include avr app ifeq ($(filter avr, $(config)), avr) apps+= apps/avr/avr.o + hdrs+= avr.h endif # include pic app ifeq ($(filter pic, $(config)), pic) - apps+= apps/pic/dspic33f.o + apps+= apps/pic/pic.o + hdrs+= pic.h endif -# include adc10 app +# include adc app ifeq ($(filter adc, $(config)), adc) ifeq ($(mcu), msp430x2274) - apps+= apps/pic/dspic33f.o + apps+= apps/adc/adc.o + hdrs+= adc.h else ERR= $(error The ADC app only works on GoodFET boards with the msp430x2274 processor) -.PHONY: err -err:;$(ERR) - endif endif # include chipcon radio spi app ifeq ($(filter ccspi, $(config)), ccspi) apps+= apps/radios/ccspi.o + hdrs+= ccspi.h endif # include nrf app ifeq ($(filter nrf, $(config)), nrf) apps+= apps/radios/nrf.o + hdrs+= nrf.h endif # include glitch app ifeq ($(filter glitch, $(config)), glitch) apps+= apps/glitch/glitch.o + hdrs+= glitch.h endif # include smartcard app ifeq ($(filter smartcard, $(config)), smartcard) apps+= apps/smartcard/smartcard.o + hdrs+= smartcard.h endif +# include ps2 app +ifeq ($(filter ps2, $(config)), ps2) + apps+= apps/plugins/ps2.o + hdrs+= ps2.h +endif # Rules @@ -249,6 +281,11 @@ lib/RUNCONFIG.o: false config: cp platforms/$(platform).h include/config.h +appsfiles: + ./gen_apps $(hdrs) +err:;$(ERR) +builddate: + ./gen_builddate_h goodfet.hex: goodfet run: @@ -256,12 +293,12 @@ run: install: $(app).hex $(BSL) -e -p $(app).hex - ls info.txt && $(BSL) -P $(app).hex -p info.txt || true #MSP430F2xx targets only, inelegant. + #ls info.txt && $(BSL) -P $(app).hex -p info.txt || true #MSP430F2xx targets only, inelegant. verify: $(BSL) -P $(app).hex -v $(app).hex dumpinfo: $(BSL) --dumpinfo -$(app).c: config +$(app).c: config builddate appsfiles err $(app): $(app).c $(libs) $(apps) $(app).hex: $(app) msp430-objcopy goodfet -O ihex goodfet.hex @@ -270,7 +307,7 @@ m4s: $(app).hex erase: $(BSL) -e clean: - rm -f $(app) $(app).hex $(libs) $(apps) include/config.h + rm -f $(app) $(app).hex $(libs) $(apps) include/config.h include/builddate.h include/apps.h docs: doxygen pushdocs: docs diff --git a/firmware/apps/adc/adc.c b/firmware/apps/adc/adc.c index becf893..e5bf083 100644 --- a/firmware/apps/adc/adc.c +++ b/firmware/apps/adc/adc.c @@ -8,12 +8,31 @@ \date September 2010 */ -#include "apps.h" #include "platform.h" #include "command.h" - #include "adc.h" +//! Handle an ADC10 command; currently assumes x2274, on a GoodFET31 board. +void adc_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the adc app's app_t +app_t const adc_app = { + + /* app number */ + ADC, + + /* handle fn */ + adc_handle_fn, + + /* name */ + "ADC", + + /* desc */ + "\tThe ADC app adds simple A/D sampling of a GoodFET pin.\n" + "\tCurrently assumes x2274 chip, on a GoodFET31 board.\n" +}; void init_adc10() { @@ -32,7 +51,9 @@ void uninit_adc10() //! Handle an ADC10 command; currently assumes x2274, on a GoodFET31 board. -void adchandle( unsigned char app, unsigned char verb, unsigned long len ) +void adc_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) { u16 sample; u16 actual_N; diff --git a/firmware/apps/avr/avr.c b/firmware/apps/avr/avr.c index 0cc4c0d..88bcf02 100644 --- a/firmware/apps/avr/avr.c +++ b/firmware/apps/avr/avr.c @@ -12,6 +12,27 @@ #include "avr.h" //#include "glitch.h" +// +//! Handles an AVR command. +void avr_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the jtag app's app_t +app_t const avr_app = { + + /* app number */ + AVR, + + /* handle fn */ + avr_handle_fn, + + /* name */ + "AVR", + + /* desc */ + "\tThe AVR app adds support for debugging AVR based devices.\n" +}; //! Setup the AVR pins. void avrsetup(){ @@ -142,10 +163,11 @@ void avr_bulk_load(u16 start, u16 len, u8 *data) { } //! Handles an AVR command. -void avrhandle(unsigned char app, - unsigned char verb, - unsigned long len){ - unsigned long i; +void avr_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ + unsigned long i, l; unsigned int at; /* @@ -212,13 +234,14 @@ void avrhandle(unsigned char app, //Fetch large blocks for bulk fetches, //small blocks for individual peeks. - if(len>2){ - len=(cmddataword[1]);//always even. + l = len; + if(l>2){ + l=(cmddataword[1]);//always even. }else{ - len=1; + l=1; } - txhead(app,verb,len); - for(i=0;i #include +//! Handles a chipcon command. +void cc_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the jtag app's app_t +app_t const chipcon_app = { + + /* app number */ + CHIPCON, + + /* handle fn */ + cc_handle_fn, + + /* name */ + "CHIPCON", + + /* desc */ + "\tThe CHIPCON app adds support for debugging the chipcon\n" + "\t8051 processor.\n" +}; /* Concerning clock rates, the maximimum clock rates are defined on page 4 of the spec. They vary, but are roughly 30MHz. Raising @@ -148,10 +169,11 @@ void ccread(unsigned char len){ cmddata[i]=cctrans8(0); } -//! Handles a monitor command. -void cchandle(unsigned char app, - unsigned char verb, - unsigned long len){ +//! Handles a chipcon command. +void cc_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ //Always init. Might help with buggy lines. //Might hurt too. //ccdebuginit(); diff --git a/firmware/apps/glitch/glitch.c b/firmware/apps/glitch/glitch.c index da94017..40e8122 100644 --- a/firmware/apps/glitch/glitch.c +++ b/firmware/apps/glitch/glitch.c @@ -11,6 +11,29 @@ #include "command.h" #include "glitch.h" +//! Handles a monitor command. +void glitch_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the glitch app's app_t +app_t const glitch_app = { + + /* app number */ + GLITCH, + + /* handle fn */ + glitch_handle_fn, + + /* name */ + "GLITCH", + + /* desc */ + "\tThe GLITCH app adds support for doing glitch research.\n" + "\tSee the TI example MSP430x261x_dac12_01.c for usage of the DAC.\n" + "\tThis module sends odd and insufficient voltages on P6.6/DAC0\n" + "\tin order to bypass security restrictions of target devices.\n" +}; //! Call this before the function to be glitched. void glitchprime(){ @@ -102,9 +125,10 @@ void glitchrate(u16 rate){ } //! Handles a monitor command. -void glitchhandle(unsigned char app, - unsigned char verb, - unsigned long len){ +void glitch_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ switch(verb){ case GLITCHVOLTAGES: glitchvoltages(cmddataword[0], diff --git a/firmware/apps/i2c/i2c.c b/firmware/apps/i2c/i2c.c index c107397..85677df 100644 --- a/firmware/apps/i2c/i2c.c +++ b/firmware/apps/i2c/i2c.c @@ -11,6 +11,7 @@ #include "platform.h" #include "command.h" +#include "i2c.h" #include #include @@ -19,6 +20,29 @@ //Pins and I/O #include + +//! Handles an i2c command. +void i2c_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the i2c app's app_t +app_t const i2c_app = { + + /* app number */ + I2C, + + /* handle fn */ + i2c_handle_fn, + + /* name */ + "I2C", + + /* desc */ + "\tThe I2C app implements the i2c bus protocol thus\n" + "\tturning your GoodFET into a USB-to-i2c adapter.\n" +}; + #define SDA TDI #define SCL TDO @@ -156,44 +180,48 @@ unsigned char I2C_Read( unsigned char ack ) } -//! Handles a monitor command. -void i2chandle(unsigned char app, - unsigned char verb, - unsigned long len){ - unsigned char i; - switch(verb){ - - case PEEK: - break; - case POKE: - break; - - case READ: - if(len>0) //optional parameter of length - len=cmddata[0]; - if(!len) //default value of 1 - len=1; - for(i=0;i 0) //optional parameter of length + l=cmddata[0]; + if(!l) //default value of 1 + l=1; + for(i = 0; i < l; i++) + cmddata[i]=I2C_Read(1); //Always acknowledge + txdata(app,verb,l); + break; + case WRITE: + cmddata[0]=0; + for(i=0;i5) - len=(cmddataword[2]);//always even. + l=(cmddataword[2]);//always even. else - len=2; - len&=~1;//clear lsbit + l=2; + l&=~1;//clear lsbit - txhead(app,verb,len); - for(i=0;i 7TDMI 20-pin connector (HE-10 connector) @@ -246,7 +277,10 @@ void jtagarm7tdmi_set_register(unsigned long reg, unsigned long val) { /////////////////////////////////////////////////////////////////////////////////////////////////// //! Handles ARM7TDMI JTAG commands. Forwards others to JTAG. -void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len){ +void jtagarm7_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ unsigned int val; switch(verb){ @@ -321,7 +355,7 @@ void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len case JTAGARM7_CHIP_ERASE: */ default: - jtaghandle(app,verb,len); + (*(jtag_app.handle))(app,verb,len); } } diff --git a/firmware/apps/jtag/jtagxscale.c b/firmware/apps/jtag/jtagxscale.c index 93cba9e..bbf9b9b 100644 --- a/firmware/apps/jtag/jtagxscale.c +++ b/firmware/apps/jtag/jtagxscale.c @@ -9,6 +9,31 @@ #include "jtag.h" #include "jtagxscale.h" +#define JTAGXSCALE_APP + +/* Handles XScale JTAG commands. Forwards others to JTAG. */ +void jtag_xscale_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the jtag xscale app's app_t +app_t const jtagxscale_app = { + + /* app number */ + JTAGXSCALE, + + /* handle fn */ + jtag_xscale_handle_fn, + + /* name */ + "JTAG XScale", + + /* desc */ + "\tThe JTAG Xscale app extends the JTAG app adding support\n" + "\tfor JTAG'ing Intel XScale devices.\n" +}; + + /* From the Intel XScale Core Developer's Manual: * * The Intel XScale® core provides test features compatible with IEEE Standard @@ -140,9 +165,9 @@ unsigned long jtag_xscale_idcode() } /* Handles XScale JTAG commands. Forwards others to JTAG. */ -void xscalehandle(unsigned char app, - unsigned char verb, - unsigned long len) +void jtag_xscale_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) { switch(verb) { diff --git a/firmware/apps/monitor/monitor.c b/firmware/apps/monitor/monitor.c index 218afca..ab6f8a4 100644 --- a/firmware/apps/monitor/monitor.c +++ b/firmware/apps/monitor/monitor.c @@ -6,108 +6,184 @@ #include "command.h" #include "platform.h" #include "monitor.h" +#include "builddate.h" + +#define MONITOR_APP + +//! Handles a monitor command. +void monitor_handle_fn(uint8_t const app, + uint8_t const verb, + uint32_t const len); + +//! Overwrite all of RAM with 0xBEEF, then reboot. +void monitor_ram_pattern(); + +//! Return the number of contiguous bytes 0xBEEF, to measure RAM usage. +unsigned int monitor_ram_depth(); //! Call a function by address. -int fncall(unsigned int adr){ - int (*machfn)() = 0; - machfn= (int (*)()) adr; - return machfn(); -} +int fncall(unsigned int adr); + + +// define the monitor app's app_t +app_t const monitor_app = { + + /* app number */ + MONITOR, + + /* handle fn */ + monitor_handle_fn, + + /* name */ + "Monitor", + + /* desc */ + "\tThe monitor app handles basic operations on the MSP430\n" + "\tsuch as peeking and poking memory, calling functions and\n" + "\tmanaging the baud rate.\n" +}; + //! Handles a monitor command. -void monitorhandle(unsigned char app, - unsigned char verb, - unsigned long len){ - switch(verb){ - default: - debugstr("ERROR: Command unsupported by debug monitor."); - break; - case MONITOR_ECHO: - //Echo back the same buffer. - txdata(app,verb,len); - break; - case PEEK: - cmddata[0]=memorybyte[cmddataword[0]]; - txdata(app,verb,1); - break; - case POKE: - //Todo, make word or byte. - memorybyte[cmddataword[0]]=cmddata[2]; - cmddata[0]=memorybyte[cmddataword[0]]; - txdata(app,verb,1); - break; - case CALL: - //Set the program counter to cmdword[0]; - cmddataword[0]=fncall(cmddataword[0]); - txdata(app,verb,2); - break; - case EXEC: - //Execute the argument as code from RAM. - cmddataword[0]=fncall((u16) cmddataword); - txdata(app,verb,2); - break; - case MONITOR_SIZEBUF: - //TODO make the data length target-specific, varying by ram. - cmddataword[0]=0x100; - txdata(app,verb,2); - break; - case MONITOR_CHANGE_BAUD: - //This command, and ONLY this command, does not reply. - setbaud(cmddata[0]); - //txdata(app,verb,0); - break; - case MONITOR_RAM_PATTERN: - monitor_ram_pattern();//reboots, will never return - break; - case MONITOR_RAM_DEPTH: - cmddataword[0]=monitor_ram_depth(); - txdata(app,verb,2); - break; - case MONITOR_DIR: - P5DIR=cmddata[0]; - txdata(app,verb,1); - break; - case MONITOR_IN: - cmddata[0]=P5IN; - txdata(app,verb,1); - break; - case MONITOR_OUT: - P5OUT=cmddata[0]; - txdata(app,verb,1); - break; - case MONITOR_SILENT: - silent=cmddata[0]; - txdata(app,verb,1); - break; - case MONITOR_CONNECTED: - msp430_init_dco_done(); - txdata(app,verb,0); - break; - } +void monitor_handle_fn(uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ + int i; + + switch(verb) + { + default: + debugstr("ERROR: Command unsupported by debug monitor."); + break; + + case MONITOR_ECHO: + //Echo back the same buffer. + txdata(app,verb,len); + break; + + case MONITOR_LIST_APPS: + // transmit firmware build date + txstring(app, verb, build_date); + + // transmit app descriptions + for(i = 0; i < num_apps; i++) + { + txstring(app, verb, apps[i]->name); + // if full list, then add in description + if(cmddata[0]) + txstring(app, verb, apps[i]->desc); + } + txdata(app, verb, 0); + break; + + case PEEK: + cmddata[0]=memorybyte[cmddataword[0]]; + txdata(app,verb,1); + break; + + case POKE: + //Todo, make word or byte. + memorybyte[cmddataword[0]] = cmddata[2]; + cmddata[0] = memorybyte[cmddataword[0]]; + txdata(app,verb,1); + break; + + case CALL: + //Set the program counter to cmdword[0]; + cmddataword[0]=fncall(cmddataword[0]); + txdata(app,verb,2); + break; + + case EXEC: + //Execute the argument as code from RAM. + cmddataword[0]=fncall((u16) cmddataword); + txdata(app,verb,2); + break; + + case MONITOR_SIZEBUF: + //TODO make the data length target-specific, varying by ram. + cmddataword[0]=0x100; + txdata(app,verb,2); + break; + + case MONITOR_CHANGE_BAUD: + //This command, and ONLY this command, does not reply. + setbaud(cmddata[0]); + //txdata(app,verb,0); + break; + + case MONITOR_RAM_PATTERN: + monitor_ram_pattern();//reboots, will never return + break; + + case MONITOR_RAM_DEPTH: + cmddataword[0]=monitor_ram_depth(); + txdata(app,verb,2); + break; + + case MONITOR_DIR: + P5DIR=cmddata[0]; + txdata(app,verb,1); + break; + + case MONITOR_IN: + cmddata[0]=P5IN; + txdata(app,verb,1); + break; + + case MONITOR_OUT: + P5OUT=cmddata[0]; + txdata(app,verb,1); + break; + + case MONITOR_SILENT: + silent=cmddata[0]; + txdata(app,verb,1); + break; + + case MONITOR_CONNECTED: + msp430_init_dco_done(); + txdata(app,verb,0); + break; + } } //! Overwrite all of RAM with 0xBEEF, then reboot. -void monitor_ram_pattern(){ - register int *a; - - //Wipe all of ram. - for(a=(int*)0x1100;a<(int*)0x2500;a++){//TODO get these from the linker. - *((int*)a) = 0xBEEF; - } - txdata(0x00,0x90,0); - - //Reboot - #ifdef MSP430 - asm("br &0xfffe"); - #endif +void monitor_ram_pattern() +{ + register int *a; + + //Wipe all of ram. + for(a=(int*)0x1100;a<(int*)0x2500;a++) + {//TODO get these from the linker. + *((int*)a) = 0xBEEF; + } + txdata(0x00,0x90,0); + + //Reboot +#ifdef MSP430 + asm("br &0xfffe"); +#endif } //! Return the number of contiguous bytes 0xBEEF, to measure RAM usage. -unsigned int monitor_ram_depth(){ - register int a; - register int count=0; - for(a=0x1100;a<0x2500;a+=2) - if(*((int*)a)==0xBEEF) count+=2; - - return count; +unsigned int monitor_ram_depth() +{ + register int a; + register int count=0; + for(a=0x1100;a<0x2500;a+=2) + if(*((int*)a)==0xBEEF) count+=2; + + return count; } + +//! Call a function by address. +int fncall(unsigned int adr) +{ + int (*machfn)() = 0; + machfn = (int (*)()) adr; + return machfn(); +} + + diff --git a/firmware/apps/pic/dspic33f.c b/firmware/apps/pic/dspic33f.c deleted file mode 100644 index 12af364..0000000 --- a/firmware/apps/pic/dspic33f.c +++ /dev/null @@ -1,335 +0,0 @@ -/*! \file dspic33f.c - - \author Scott Livingston - - \brief dsPIC33F programmer application for the GoodFET. Structure - and style is somewhat modeled after avr.c - - \date March-May 2010 -*/ - - -#include "apps.h" -#include "platform.h" -#include "command.h" - -#include "dspic33f.h" - - -void pic33f_setup() -{ - // Initialize pins; do NOT begin transaction. - P5DIR |= PGC|MCLR; - P5REN &= ~(PGC|PGD|MCLR); - DIR_PGD_WR; // Initially PGD in write mode - - SET_MCLR; - CLR_PGC; - CLR_PGD; - - prep_timer(); // What better time than now? -} - - -//! Handle a PIC command; currently assumes dsPIC33F/PIC24H -void pichandle( unsigned char app, - unsigned char verb, - unsigned long len ) -{ - unsigned int nb; // Number of bytes - unsigned int highb, loww; // Used for ICSP commands - - switch (verb) { - - case PIC_DEVID33F: - nb = pic33f_getid(); - txdata(app,verb,nb); - break; - - case PIC_SIX33F: - loww = *cmddata; - loww |= (*(cmddata+1)) << 8; - highb = *(cmddata+2); - pic33f_six( highb, loww ); - txdata(app,verb,0); - break; - - case PIC_SIXLIST33F: - pic33f_sixlist( len ); // Reply to host is handled by pic33f_sixlist. - break; - - case PIC_REGOUT33F: - loww = pic33f_regout(); - *cmddata = loww & 0xff; - *(cmddata+1) = loww >> 8; - txdata(app,verb,2); - break; - - case PIC_RESET33F: - CLR_MCLR; - delay_ms(20); - SET_MCLR; - break; - - case PIC_START33F: - pic33f_connect(); - txdata(app,verb,0); - break; - - case PIC_STOP33F: - pic33f_disconnect(); - txdata(app,verb,0); - break; - - default: - debugstr( "Verb unimplemented in PIC application." ); - txdata(app,NOK,0); - break; - - } -} - - -void pic33f_trans8( unsigned char byte ) -{ - /* We only twiddle the PGD and PGC lines. - MCLR is assumed to be in the correct state. */ - unsigned int i; - - DIR_PGD_WR; // Write mode - i = 1; - while (i & 0xff) { - if (byte & i) { - SET_PGD; - } else { - CLR_PGD; - } - delay_ticks(10); - SET_PGC; - delay_ticks(10); - - CLR_PGC; - delay_ticks(10); - i = i << 1; - } - CLR_PGD; - DIR_PGD_RD; // Read mode -} - -void pic33f_trans16( unsigned int word ) -{ - pic33f_trans8( word & 0xff ); - pic33f_trans8( word >> 8 ); -} - - -void pic33f_six( unsigned int highb, unsigned int loww ) -{ - /* dsPIC33F/PIC24H instructions have width 24 bits, so we use the - lower 8 bits of highb and (all 16 bits of) loww to form the - instruction. - - Shift in the instruction. Note that it does not execute until - the next 4 clock cycles (which also corresponds to a command - receipt time). */ - unsigned int i; - DIR_PGD_WR; - CLR_PGD; - CLR_PGC; - for (i = 0; i < 4; i++) { - SET_PGC; - delay_ticks(10); - CLR_PGC; - delay_ticks(10); - } - pic33f_trans16( loww ); - pic33f_trans8( highb ); - DIR_PGD_RD; -} - - -unsigned int pic33f_regout() -{ - unsigned int i; - unsigned int result = 0x0000; - - DIR_PGD_WR; - - // Shift in command (REGOUT: 0001b). - SET_PGD; - delay_ticks(10); - SET_PGC; - delay_ticks(10); - CLR_PGC; - delay_ticks(10); - - CLR_PGD; - delay_ticks(10); - for (i = 0; i < 3; i++) { - SET_PGC; - delay_ticks(10); - CLR_PGC; - delay_ticks(10); - } - - // Pump clock for 8 cycles, and switch PGD direction to read. - for (i = 0; i < 7; i++) { - SET_PGC; - delay_ticks(10); - CLR_PGC; - delay_ticks(10); - } - DIR_PGD_RD; - - /* Now read VISI register (LSb first, as usual). - Note that when reading from attached device, data is valid (to - be read) on falling clock edges. */ - for (i = 0; i < 16; i++) { - SET_PGC; - delay_ticks(10); - CLR_PGC; - result |= READ_PGD << i; - delay_ticks(10); - } - - /* One last tick apparently is needed here, at least by the - dsPIC33FJ128GP708 chip that I am working with. Note that this - is not in the flash programming specs. */ - SET_PGC; - delay_ticks(10); - CLR_PGC; - delay_ticks(10); - - return result; -} - - -void pic33f_sixlist( unsigned int list_len ) -{ - unsigned int k; - unsigned int instr_loww; - - // Bound to Rx buffer size. - if (list_len > CMDDATALEN) - list_len = CMDDATALEN; - - // Run each instruction! - for (k = 0; k < list_len-2; k+=3) { - instr_loww = *(cmddata+k); - instr_loww |= (*(cmddata+k+1)) << 8; - pic33f_six( *(cmddata+k+2), instr_loww ); - } - - // Reply with total number of bytes used from Rx buffer. - txdata( PIC, PIC_SIXLIST33F, k ); -} - - -unsigned int pic33f_getid() -{ - unsigned int result; - unsigned int nb = 0; - - pic33f_connect(); - - // Read application ID. - pic33f_six( 0x04, 0x0200 ); // goto 0x200 (i.e. reset) - pic33f_six( 0x00, 0x0000 ); // nop - pic33f_six( 0x20, 0x0800 ); // mov #0x80, W0 - pic33f_six( 0x88, 0x0190 ); // mov W0, TBLPAG - pic33f_six( 0x20, 0x7F00 ); // mov #0x7F0, W0 - pic33f_six( 0x20, 0x7841 ); // mov #VISI, W1 - pic33f_six( 0x00, 0x0000 ); // nop - pic33f_six( 0xBA, 0x0890 ); // TBLRDL [W0], [W1] - pic33f_six( 0x00, 0x0000 ); // nop - pic33f_six( 0x00, 0x0000 ); // nop - result = pic33f_regout(); - *cmddata = result & 0xff; - nb += 1; - - // Read DEVID. - pic33f_six( 0x20, 0x0FF0 ); // mov #0xFF, W0 - pic33f_six( 0x88, 0x0190 ); // mov W0, TBLPAG - pic33f_six( 0xEB, 0x0000 ); // clr W0 - pic33f_six( 0x00, 0x0000 ); // nop - pic33f_six( 0xBA, 0x08B0 ); // TBLRDL [W0++], [W1] - pic33f_six( 0x00, 0x0000 ); // nop - pic33f_six( 0x00, 0x0000 ); // nop - result = pic33f_regout(); - *(cmddata+1) = result & 0xff; - *(cmddata+2) = result >> 8; - nb += 2; - - // Read hardware revision. - pic33f_six( 0xBA, 0x0890 ); // TBLRDL [W0++], [W1] - pic33f_six( 0x00, 0x0000 ); // nop - pic33f_six( 0x00, 0x0000 ); // nop - result = pic33f_regout(); - *(cmddata+3) = result & 0xff; - *(cmddata+4) = result >> 8; - nb += 2; - - pic33f_disconnect(); - - return nb; -} - - -void pic33f_connect() -{ - unsigned int key_low; - unsigned int key_high; - - key_low = ICSP_KEY_LOW; - key_high = ICSP_KEY_HIGH; - - pic33f_setup(); - - CLR_PGC; - delay_us(1); - - CLR_MCLR; - delay_ms(3); - SET_MCLR; - delay_us(200); - CLR_MCLR; - delay_us(10); - - // Enter ICSP key - pic33f_trans8( key_low & 0xff ); - key_low = key_low >> 8; - pic33f_trans8( key_low & 0xff ); - pic33f_trans8( key_high & 0xff ); - key_high = key_high >> 8; - pic33f_trans8( key_high & 0xff ); - - delay_us(1); - SET_MCLR; // ...and pull MCLR pin back up. - delay_ms(25); // Now wait about 25 ms (required per spec!). - - /* The first ICSP command must be a SIX, and further, 9 bits are - required before the instruction (to be executed), rather than - the typical 4 bits. Thus, to simplify code, I simply load a nop - here; hence 33 bits are shifted into the dsPIC33F/PIC24H. */ - DIR_PGD_WR; - CLR_PGD; - CLR_PGC; - for (key_low = 0; key_low < 33; key_low++) { - SET_PGC; - delay_us(1); - CLR_PGC; - delay_us(1); - } - DIR_PGD_RD; - -} - - -void pic33f_disconnect() -{ - DIR_PGD_WR; - CLR_PGD; - CLR_PGC; - delay_ms(10); - CLR_MCLR; -} diff --git a/firmware/apps/pic/pic.c b/firmware/apps/pic/pic.c new file mode 100644 index 0000000..4e25fea --- /dev/null +++ b/firmware/apps/pic/pic.c @@ -0,0 +1,355 @@ +/*! \file dspic33f.c + + \author Scott Livingston + + \brief dsPIC33F programmer application for the GoodFET. Structure + and style is somewhat modeled after avr.c + + \date March-May 2010 +*/ + + +#include "platform.h" +#include "command.h" + +#include "pic.h" + +//! Handle a PIC command; currently assumes dsPIC33F/PIC24H +void pic_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len ); + +// define the pic app's app_t +app_t const pic_app = { + + /* app number */ + PIC, + + /* handle fn */ + pic_handle_fn, + + /* name */ + "PIC", + + /* desc */ + "\tThe PIC app adds support for programming/debugging\n" + "\tdsPIC33F based devices.\n" +}; + +void pic33f_setup() +{ + // Initialize pins; do NOT begin transaction. + P5DIR |= PGC|MCLR; + P5REN &= ~(PGC|PGD|MCLR); + DIR_PGD_WR; // Initially PGD in write mode + + SET_MCLR; + CLR_PGC; + CLR_PGD; + + prep_timer(); // What better time than now? +} + + +//! Handle a PIC command; currently assumes dsPIC33F/PIC24H +void pic_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len ) +{ + unsigned int nb; // Number of bytes + unsigned int highb, loww; // Used for ICSP commands + + switch (verb) { + + case PIC_DEVID33F: + nb = pic33f_getid(); + txdata(app,verb,nb); + break; + + case PIC_SIX33F: + loww = *cmddata; + loww |= (*(cmddata+1)) << 8; + highb = *(cmddata+2); + pic33f_six( highb, loww ); + txdata(app,verb,0); + break; + + case PIC_SIXLIST33F: + pic33f_sixlist( len ); // Reply to host is handled by pic33f_sixlist. + break; + + case PIC_REGOUT33F: + loww = pic33f_regout(); + *cmddata = loww & 0xff; + *(cmddata+1) = loww >> 8; + txdata(app,verb,2); + break; + + case PIC_RESET33F: + CLR_MCLR; + delay_ms(20); + SET_MCLR; + break; + + case PIC_START33F: + pic33f_connect(); + txdata(app,verb,0); + break; + + case PIC_STOP33F: + pic33f_disconnect(); + txdata(app,verb,0); + break; + + default: + debugstr( "Verb unimplemented in PIC application." ); + txdata(app,NOK,0); + break; + + } +} + + +void pic33f_trans8( unsigned char byte ) +{ + /* We only twiddle the PGD and PGC lines. + MCLR is assumed to be in the correct state. */ + unsigned int i; + + DIR_PGD_WR; // Write mode + i = 1; + while (i & 0xff) { + if (byte & i) { + SET_PGD; + } else { + CLR_PGD; + } + delay_ticks(10); + SET_PGC; + delay_ticks(10); + + CLR_PGC; + delay_ticks(10); + i = i << 1; + } + CLR_PGD; + DIR_PGD_RD; // Read mode +} + +void pic33f_trans16( unsigned int word ) +{ + pic33f_trans8( word & 0xff ); + pic33f_trans8( word >> 8 ); +} + + +void pic33f_six( unsigned int highb, unsigned int loww ) +{ + /* dsPIC33F/PIC24H instructions have width 24 bits, so we use the + lower 8 bits of highb and (all 16 bits of) loww to form the + instruction. + + Shift in the instruction. Note that it does not execute until + the next 4 clock cycles (which also corresponds to a command + receipt time). */ + unsigned int i; + DIR_PGD_WR; + CLR_PGD; + CLR_PGC; + for (i = 0; i < 4; i++) { + SET_PGC; + delay_ticks(10); + CLR_PGC; + delay_ticks(10); + } + pic33f_trans16( loww ); + pic33f_trans8( highb ); + DIR_PGD_RD; +} + + +unsigned int pic33f_regout() +{ + unsigned int i; + unsigned int result = 0x0000; + + DIR_PGD_WR; + + // Shift in command (REGOUT: 0001b). + SET_PGD; + delay_ticks(10); + SET_PGC; + delay_ticks(10); + CLR_PGC; + delay_ticks(10); + + CLR_PGD; + delay_ticks(10); + for (i = 0; i < 3; i++) { + SET_PGC; + delay_ticks(10); + CLR_PGC; + delay_ticks(10); + } + + // Pump clock for 8 cycles, and switch PGD direction to read. + for (i = 0; i < 7; i++) { + SET_PGC; + delay_ticks(10); + CLR_PGC; + delay_ticks(10); + } + DIR_PGD_RD; + + /* Now read VISI register (LSb first, as usual). + Note that when reading from attached device, data is valid (to + be read) on falling clock edges. */ + for (i = 0; i < 16; i++) { + SET_PGC; + delay_ticks(10); + CLR_PGC; + result |= READ_PGD << i; + delay_ticks(10); + } + + /* One last tick apparently is needed here, at least by the + dsPIC33FJ128GP708 chip that I am working with. Note that this + is not in the flash programming specs. */ + SET_PGC; + delay_ticks(10); + CLR_PGC; + delay_ticks(10); + + return result; +} + + +void pic33f_sixlist( unsigned int list_len ) +{ + unsigned int k; + unsigned int instr_loww; + + // Bound to Rx buffer size. + if (list_len > CMDDATALEN) + list_len = CMDDATALEN; + + // Run each instruction! + for (k = 0; k < list_len-2; k+=3) { + instr_loww = *(cmddata+k); + instr_loww |= (*(cmddata+k+1)) << 8; + pic33f_six( *(cmddata+k+2), instr_loww ); + } + + // Reply with total number of bytes used from Rx buffer. + txdata( PIC, PIC_SIXLIST33F, k ); +} + + +unsigned int pic33f_getid() +{ + unsigned int result; + unsigned int nb = 0; + + pic33f_connect(); + + // Read application ID. + pic33f_six( 0x04, 0x0200 ); // goto 0x200 (i.e. reset) + pic33f_six( 0x00, 0x0000 ); // nop + pic33f_six( 0x20, 0x0800 ); // mov #0x80, W0 + pic33f_six( 0x88, 0x0190 ); // mov W0, TBLPAG + pic33f_six( 0x20, 0x7F00 ); // mov #0x7F0, W0 + pic33f_six( 0x20, 0x7841 ); // mov #VISI, W1 + pic33f_six( 0x00, 0x0000 ); // nop + pic33f_six( 0xBA, 0x0890 ); // TBLRDL [W0], [W1] + pic33f_six( 0x00, 0x0000 ); // nop + pic33f_six( 0x00, 0x0000 ); // nop + result = pic33f_regout(); + *cmddata = result & 0xff; + nb += 1; + + // Read DEVID. + pic33f_six( 0x20, 0x0FF0 ); // mov #0xFF, W0 + pic33f_six( 0x88, 0x0190 ); // mov W0, TBLPAG + pic33f_six( 0xEB, 0x0000 ); // clr W0 + pic33f_six( 0x00, 0x0000 ); // nop + pic33f_six( 0xBA, 0x08B0 ); // TBLRDL [W0++], [W1] + pic33f_six( 0x00, 0x0000 ); // nop + pic33f_six( 0x00, 0x0000 ); // nop + result = pic33f_regout(); + *(cmddata+1) = result & 0xff; + *(cmddata+2) = result >> 8; + nb += 2; + + // Read hardware revision. + pic33f_six( 0xBA, 0x0890 ); // TBLRDL [W0++], [W1] + pic33f_six( 0x00, 0x0000 ); // nop + pic33f_six( 0x00, 0x0000 ); // nop + result = pic33f_regout(); + *(cmddata+3) = result & 0xff; + *(cmddata+4) = result >> 8; + nb += 2; + + pic33f_disconnect(); + + return nb; +} + + +void pic33f_connect() +{ + unsigned int key_low; + unsigned int key_high; + + key_low = ICSP_KEY_LOW; + key_high = ICSP_KEY_HIGH; + + pic33f_setup(); + + CLR_PGC; + delay_us(1); + + CLR_MCLR; + delay_ms(3); + SET_MCLR; + delay_us(200); + CLR_MCLR; + delay_us(10); + + // Enter ICSP key + pic33f_trans8( key_low & 0xff ); + key_low = key_low >> 8; + pic33f_trans8( key_low & 0xff ); + pic33f_trans8( key_high & 0xff ); + key_high = key_high >> 8; + pic33f_trans8( key_high & 0xff ); + + delay_us(1); + SET_MCLR; // ...and pull MCLR pin back up. + delay_ms(25); // Now wait about 25 ms (required per spec!). + + /* The first ICSP command must be a SIX, and further, 9 bits are + required before the instruction (to be executed), rather than + the typical 4 bits. Thus, to simplify code, I simply load a nop + here; hence 33 bits are shifted into the dsPIC33F/PIC24H. */ + DIR_PGD_WR; + CLR_PGD; + CLR_PGC; + for (key_low = 0; key_low < 33; key_low++) { + SET_PGC; + delay_us(1); + CLR_PGC; + delay_us(1); + } + DIR_PGD_RD; + +} + + +void pic33f_disconnect() +{ + DIR_PGD_WR; + CLR_PGD; + CLR_PGC; + delay_ms(10); + CLR_MCLR; +} diff --git a/firmware/apps/plugins/ps2.c b/firmware/apps/plugins/ps2.c index df31503..b751416 100644 --- a/firmware/apps/plugins/ps2.c +++ b/firmware/apps/plugins/ps2.c @@ -11,6 +11,30 @@ #include "ps2.h" #include "jtag.h" +//! Handles a monitor command. +void ps2_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + + +// define the ps2 app's app_t +app_t const ps2_app = { + + /* app number */ + PS2, + + /* handle fn */ + ps2_handle_fn, + + /* name */ + "PS2", + + /* desc */ + "\tThe PS2 app spies on PS/2. For now, it just reports the\n" + "\tinter-character timing information.\n" +}; + + u32 mclock=0; u32 clock=0; @@ -29,15 +53,12 @@ interrupt(TIMERA0_VECTOR) Timer_A (void) TDO P5.2 */ -// This is just a plugin for now. -#define ps2handle pluginhandle - u32 oldclock=0; //! Handles a monitor command. -int ps2handle(unsigned char app, - unsigned char verb, - unsigned int len){ - +void ps2_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ switch(verb){ case START: WDTCTL = WDTPW + WDTHOLD; // Stop WDT diff --git a/firmware/apps/radios/ccspi.c b/firmware/apps/radios/ccspi.c index 6fdea29..ab1051f 100644 --- a/firmware/apps/radios/ccspi.c +++ b/firmware/apps/radios/ccspi.c @@ -20,6 +20,32 @@ #include "ccspi.h" #include "spi.h" +//! Handles a Chipcon SPI command. +void ccspi_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the ccspi app's app_t +app_t const ccspi_app = { + + /* app number */ + CCSPI, + + /* handle fn */ + ccspi_handle_fn, + + /* name */ + "CCSPI", + + /* desc */ + "\tThe CCSPI app adds support for the Chipcon SPI register\n" + "\tinterface. Unfortunately, there is very little similarity\n" + "\tbetween the CC2420 and the CC2500, to name just two of the\n" + "\tmyriad of Chipcon SPI radios. Auto-detection will be a bit\n" + "\tdifficult, but more to the point, all high level functionality\n" + "\tmust be moved into the client.\n" +}; + #define RADIOACTIVE SETCE #define RADIOPASSIVE CLRCE @@ -86,9 +112,10 @@ u8 ccspi_regread(u8 reg, u8 *buf, int len){ } //! Handles a Chipcon SPI command. -void ccspihandle(unsigned char app, - unsigned char verb, - unsigned long len){ +void ccspi_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ unsigned long i; //Drop CE to passify radio. diff --git a/firmware/apps/radios/nrf.c b/firmware/apps/radios/nrf.c index ca70113..0b1b6bd 100644 --- a/firmware/apps/radios/nrf.c +++ b/firmware/apps/radios/nrf.c @@ -15,6 +15,27 @@ #include "nrf.h" #include "spi.h" +//! Handles a Nordic RF command. +void nrf_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the nrf app's app_t +app_t const nrf_app = { + + /* app number */ + NRF, + + /* handle fn */ + nrf_handle_fn, + + /* name */ + "NRF", + + /* desc */ + "\tThe NRF app adds support for the NordicRF register\n" + "\tinterface.\n" +}; #define RADIOACTIVE SETCE #define RADIOPASSIVE CLRCE @@ -81,9 +102,10 @@ u8 nrf_regread(u8 reg, u8 *buf, int len){ } //! Handles a Nordic RF command. -void nrfhandle(unsigned char app, - unsigned char verb, - unsigned long len){ +void nrf_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ unsigned long i; //Drop CE to passify radio. diff --git a/firmware/apps/smartcard/smartcard.c b/firmware/apps/smartcard/smartcard.c index db32de2..93beb3a 100644 --- a/firmware/apps/smartcard/smartcard.c +++ b/firmware/apps/smartcard/smartcard.c @@ -8,6 +8,30 @@ #include "platform.h" #include "command.h" #include "jtag.h" +#include "smartcard.h" + +//! Handles a monitor command. +void smartcard_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the smartcard app's app_t +app_t const smartcard_app = { + + /* app number */ + SMARTCARD, + + /* handle fn */ + smartcard_handle_fn, + + /* name */ + "SMARTCARD", + + /* desc */ + "\tThe SMARTCARD app allows for communication with smart\n" + "\tcards and SIM cards.\n" +}; + //TDO/P5.2 is Data @@ -35,9 +59,10 @@ void smartcardsetup(){ u16 sctime=0, foo=0; //! Handles a monitor command. -int smartcardhandle(unsigned char app, - unsigned char verb, - unsigned int len){ +void smartcard_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ switch(verb){ case SETUP: smartcardsetup(); @@ -74,5 +99,4 @@ int smartcardhandle(unsigned char app, debugstr("Unknown smartcard verb."); txdata(app,NOK,0); } - return 0; } diff --git a/firmware/apps/spi/spi.c b/firmware/apps/spi/spi.c index dc1c286..e07cdb5 100644 --- a/firmware/apps/spi/spi.c +++ b/firmware/apps/spi/spi.c @@ -14,6 +14,28 @@ #include "spi.h" +//! Handles a monitor command. +void spi_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the spi app's app_t +app_t const spi_app = { + + /* app number */ + SPI, + + /* handle fn */ + spi_handle_fn, + + /* name */ + "SPI", + + /* desc */ + "\tThe SPI app handles the SPI bus protocol, turning\n" + "\tyour GoodFET into a USB-to-SPI adapter.\n" +}; + //This could be more accurate. //Does it ever need to be? #define SPISPEED 0 @@ -299,73 +321,68 @@ void spi_rw_em260(u8 app, u8 verb, u32 len){ } //! Handles a monitor command. -void spihandle(unsigned char app, - unsigned char verb, - unsigned long len){ - unsigned long i; - - - //Raise !SS to end transaction, just in case we forgot. - SETSS; - //spisetup(); - - switch(verb){ - //PEEK and POKE might come later. - case READ: - case WRITE: - CLRSS; //Drop !SS to begin transaction. - for(i=0;i> fout, "#ifndef APPS_H" + print >> fout, "#define APPS_H" + print >> fout, "#include \"app.h\"" + for app in sys.argv[1:]: + print >> fout, '#include "%s"' % app + print >> fout, "#endif" + fout.close() + + cout = open("lib/apps.c", "w+") + print >> cout, "#include " + print >> cout, "#include \"app.h\"" + print >> cout, "#include \"apps.h\"" + print >> cout, "app_t const * const apps[] = {" + for app in sys.argv[1:]: + print >> cout, "#ifdef %s_H" % app.split('.')[0].upper() + print >> cout, "\t&%s_app," % app.split('.')[0] + print >> cout, "#endif" + print >> cout, "};" + print >> cout, "int const num_apps = sizeof(apps) / sizeof(app_t*);" + cout.close() + + return 0 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/firmware/gen_builddate_h b/firmware/gen_builddate_h new file mode 100755 index 0000000..04e2ae2 --- /dev/null +++ b/firmware/gen_builddate_h @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import sys +import datetime + +def main(): + fout = open("include/builddate.h", "w+") + print >> fout, "#ifndef BUILDDATE_H" + print >> fout, "#define BUILDDATE_H" + print >> fout, "char const * const build_date=\"%s\";" % datetime.datetime.now().strftime("%Y-%m-%d %H:%M") + print >> fout, "#endif" + fout.close() + return 0 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/firmware/goodfet.c b/firmware/goodfet.c index 8be9a74..c7563e6 100644 --- a/firmware/goodfet.c +++ b/firmware/goodfet.c @@ -12,203 +12,178 @@ #include "apps.h" #include "glitch.h" +#define RESET 0x80 // not a real app -- causes firmware to reset +#define DEBUGAPP 0xFF //! Initialize registers and all that jazz. -void init(){ - #ifdef DAC12IR - int i; - #endif - - WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer - - //LED out and on. - PLEDDIR |= PLEDPIN; - PLEDOUT &= ~PLEDPIN; +void init() +{ +#ifdef DAC12IR + int i; +#endif + WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer - /* P5.0 out and low; this is chosen for the PIC app (in which P5.0 + //LED out and on. + PLEDDIR |= PLEDPIN; + PLEDOUT &= ~PLEDPIN; + + + /* P5.0 out and low; this is chosen for the PIC app (in which P5.0 is !MCLR) to ensure that an attached PIC chip, if present, is immediately driven to reset state. A brief explanation of why this is important follows. - At least dsPIC33F and PIC24H --and very likely other 16-bit PIC - families-- draw a large amount of current when running, especially - when using a fast clock: from 60 mA up to approx. 90 mA. If the - PIC target begins to run before the client can request a new ICSP - session, which requires much less current (e.g., less than 2 mA), - then the MSP430 chip on the GoodFET will fail to start and the FTDI - may have trouble communicating with the client. The latter likely - relates to the FTDI on-chip 3V3 regulator being specified up to - only 50 mA. */ - - - //P5REN &= ~BIT0; //DO NOT UNCOMMENT. Breaks GF1x support. - - //This will have to be cut soon. Use pulling resistors instead. - /* - P5DIR |= BIT0; - P5OUT &= ~BIT0; - */ - - //Setup clocks, unique to each '430. - msp430_init_dco(); - msp430_init_uart(); + At least dsPIC33F and PIC24H --and very likely other 16-bit PIC + families-- draw a large amount of current when running, especially + when using a fast clock: from 60 mA up to approx. 90 mA. If the + PIC target begins to run before the client can request a new ICSP + session, which requires much less current (e.g., less than 2 mA), + then the MSP430 chip on the GoodFET will fail to start and the FTDI + may have trouble communicating with the client. The latter likely + relates to the FTDI on-chip 3V3 regulator being specified up to + only 50 mA. */ + + + //P5REN &= ~BIT0; //DO NOT UNCOMMENT. Breaks GF1x support. + + //This will have to be cut soon. Use pulling resistors instead. + /* + P5DIR |= BIT0; + P5OUT &= ~BIT0; + */ - //DAC should be at full voltage if it exists. + //Setup clocks, unique to each '430. + msp430_init_dco(); + msp430_init_uart(); + + //DAC should be at full voltage if it exists. #ifdef DAC12IR - //glitchvoltages(0xfff,0xfff); - ADC12CTL0 = REF2_5V + REFON; // Internal 2.5V ref on - for(i=0;i!=0xFFFF;i++) asm("nop"); - DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1 - DAC12_0DAT = 0xFFF; //Max voltage 0xfff - DAC12_1CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1 - DAC12_1DAT = 0x000; //Min voltage 0x000 + //glitchvoltages(0xfff,0xfff); + ADC12CTL0 = REF2_5V + REFON; // Internal 2.5V ref on + for(i=0;i!=0xFFFF;i++) asm("nop"); + DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1 + DAC12_0DAT = 0xFFF; //Max voltage 0xfff + DAC12_1CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1 + DAC12_1DAT = 0x000; //Min voltage 0x000 #endif - - /** FIXME - - This part is really ugly. GSEL (P5.7) must be high to select - normal voltage, but a lot of applications light to swing it low - to be a nuissance. To get around this, we assume that anyone - with a glitching FET will also have a DAC, then we set that DAC - to a high voltage. - - At some point, each target must be sanitized to show that it - doesn't clear P5OUT or P5DIR. - */ - P5DIR|=BIT7; P5OUT=BIT7; //Normal Supply - //P5DIR&=~BIT7; //Glitch Supply - - //Enable Interrupts. - //eint(); + + /** FIXME + + This part is really ugly. GSEL (P5.7) must be high to select + normal voltage, but a lot of applications light to swing it low + to be a nuissance. To get around this, we assume that anyone + with a glitching FET will also have a DAC, then we set that DAC + to a high voltage. + + At some point, each target must be sanitized to show that it + doesn't clear P5OUT or P5DIR. + */ + P5DIR|=BIT7; P5OUT=BIT7; //Normal Supply + //P5DIR&=~BIT7; //Glitch Supply + + //Enable Interrupts. + //eint(); } //! Handle a command. -void handle(unsigned char app, - unsigned char verb, - unsigned long len){ - //debugstr("GoodFET"); - PLEDOUT&=~PLEDPIN; - switch(app){ - case GLITCH: - glitchhandle(app,verb,len); - break; - case MONITOR: - monitorhandle(app,verb,len); - break; - case SPI: - spihandle(app,verb,len); - break; - case NRF: - nrfhandle(app,verb,len); - break; - case CCSPI: - ccspihandle(app,verb,len); - break; - case AVR: - avrhandle(app,verb,len); - break; - case PIC: - pichandle(app,verb,len); - break; - case ADC10: - adchandle(app,verb,len); - break; - case I2CAPP: - i2chandle(app,verb,len); - break; - case CHIPCON: - cchandle(app,verb,len); - break; - case JTAG: - jtaghandle(app,verb,len); - break; - case EJTAG: - ejtaghandle(app,verb,len); - break; - case JTAGXSCALE: - xscalehandle(app,verb,len); - break; - case JTAG430: //Also JTAG430X, JTAG430X2 - //Revert this when X2 support returns. - jtag430x2handle(app,verb,len); - //jtag430handle(app,verb,len); - break; - case SMARTCARD: - smartcardhandle(app,verb,len); - break; - case JTAGARM7TDMI: - jtagarm7tdmihandle(app,verb,len); - break; - default: - if(pluginhandle){ - pluginhandle(app,verb,len); - }else{ - debugstr("Plugin missing."); - debughex(app); - txdata(app,NOK,0); - } - break; - } +void handle(uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ + int i; + + //debugstr("GoodFET"); + PLEDOUT&=~PLEDPIN; + + // find the app and call the handle fn + for(i = 0; i < num_apps; i++) + { + if(apps[i]->app == app) + { + // call the app's handle fn + (*(apps[i]->handle))(app, verb, len); + + // exit early + return; + } + } + + // if we get here, then the desired app is not copiled in + // this firmware + debugstr("App missing."); + debughex(app); + txdata(app, NOK, 0); } + //! Main loop. int main(void) { - volatile unsigned int i; - unsigned char app, verb; - unsigned long len; - // MSP reboot count for reset input & reboot function located at 0xFFFE - volatile unsigned int reset_count = 0; - void (*reboot_function)(void) = (void *) 0xFFFE; - - init(); - - txstring(MONITOR,OK,"http://goodfet.sf.net/"); + volatile unsigned int i; + unsigned char app, verb; + unsigned long len; + // MSP reboot count for reset input & reboot function located at 0xFFFE + volatile unsigned int reset_count = 0; + void (*reboot_function)(void) = (void *) 0xFFFE; + + init(); + txstring(MONITOR,OK,"http://goodfet.sf.net/"); - //Command loop. There's no end! - while(1){ - //Magic 3 - app=serial_rx(); - - // If the app is the reset byte (0x80) increment and loop - if (app == RESET) { - reset_count++; - - if (reset_count > 4) { - // We could trigger the WDT with either: - // WDTCTL = 0; - // or - // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00; - // but instead we'll jump to our reboot function pointer - (*reboot_function)(); - } - - continue; - } else { - reset_count = 0; - } - - verb=serial_rx(); - //len=serial_rx(); - len=rxword(); - - //Read data, looking for buffer overflow.y - if(len<=CMDDATALEN){ - for(i=0;i 4) + { + // We could trigger the WDT with either: + // WDTCTL = 0; + // or + // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00; + // but instead we'll jump to our reboot function pointer + (*reboot_function)(); + } + + continue; + } + else + { + reset_count = 0; + } + + verb = serial_rx(); + //len=serial_rx(); + len = rxword(); + + //Read data, looking for buffer overflow.y + if(len <= CMDDATALEN) + { + for(i = 0; i < len; i++) + { + cmddata[i] = serial_rx(); + } + + handle(app,verb,len); + } + else + { + //Listen to the blaberring. + for(i = 0; i < len; i++) + serial_rx(); + + //Reply with an error. + debugstr("Buffer length exceeded."); + txdata(MONITOR,NOK,0); + } + } } diff --git a/firmware/include/adc.h b/firmware/include/adc.h index ad06a89..e731f5c 100644 --- a/firmware/include/adc.h +++ b/firmware/include/adc.h @@ -13,12 +13,13 @@ \date September 2010 */ +#ifndef ADC_H +#define ADC_H -// Identical to that in command.h, but to avoid cyclic dependencies... -#define u8 unsigned char -#define u16 unsigned int -#define u32 unsigned long +#include "command.h" +#include "app.h" +#define ADC 0x74 //! Initialize ADC10 module (specific to 2xx chip family). void init_adc10(); @@ -69,3 +70,8 @@ u16 nsamples_adc10( u8 N_count, //! Number samples to obtain (bounded w.r.t. cmd 1 => user-specified sequence length, t_sample = 3, clock_div = 8; 3 => user-specified length, t_sample and clock_div. */ #define ADC10_NSAMPLE 0x84 + +extern app_t const adc_app; + +#endif // ADC_H + diff --git a/firmware/include/app.h b/firmware/include/app.h new file mode 100644 index 0000000..2ffb84a --- /dev/null +++ b/firmware/include/app.h @@ -0,0 +1,32 @@ +/*! \file app.h + * \author Dave Huseby + * \brief basic types for defining a firmware app + */ + +#ifndef APP_H +#define APP_H + +// this is the prototype for all app "handle" functions +typedef void (*handle_fn)(uint8_t app, + uint8_t verb, + uint32_t len); + +// Each app must declare one of these +typedef struct app_ +{ + uint8_t const app; /* app number */ + handle_fn const handle; /* handle fn ptr */ + char const * const name; /* name of the app */ + char const * const desc; /* app description */ +} app_t; + +// The following externs give all apps access to the app list + +// Global list of app_t's for all compiled in apps +extern app_t const * const apps[]; + +// Global number of apps in the app list +extern int const num_apps; + +#endif + diff --git a/firmware/include/apps.h b/firmware/include/apps.h deleted file mode 100644 index 47a9167..0000000 --- a/firmware/include/apps.h +++ /dev/null @@ -1,40 +0,0 @@ -/*! \file apps.h - \author Travis Goodspeed - \brief Application definitions. -*/ - -//Essential and highly standardized stuff in 0x00 range. -#define MONITOR 0x00 -#define SPI 0x01 -#define I2CAPP 0x02 - -//All JTAG targets in 0x10 range. -#define JTAG 0x10 -#define JTAG430 0x11 -#define EJTAG 0x12 -#define JTAGARM7TDMI 0x13 -#define ADIv5 0x14 -#define JTAGXSCALE 0x15 - -//Manufacturer-specific protocols go in 0x30 and 0x40. -#define CHIPCON 0x30 -#define SIF 0x31 -#define AVR 0x32 -#define PIC 0x34 - -//Radio peripherals are in the 0x50 range. -#define NRF 0x50 -#define CCSPI 0x51 - -//Keep 0x60 empty for now. - -//Weird stuff in 0x70 range. -#define OCT 0x70 -#define GLITCH 0x71 -#define PLUGIN 0x72 -#define SMARTCARD 0x73 -#define ADC10 0x74 - -#define RESET 0x80 // not a real app -- causes firmware to reset - -#define DEBUGAPP 0xFF diff --git a/firmware/include/avr.h b/firmware/include/avr.h index f0e8614..bcf76ef 100644 --- a/firmware/include/avr.h +++ b/firmware/include/avr.h @@ -3,7 +3,13 @@ \brief AVR SPI Programmer */ +#ifndef AVR_H +#define AVR_H + #include "spi.h" +#include "app.h" + +#define AVR 0x32 //! Setup the AVR pins. void avrsetup(); @@ -57,3 +63,7 @@ u8 avr_isready(); #define AVR_READCAL 0x85 //! Bulk load data #define AVR_BULKLOAD 0x86 + +extern app_t const avr_app; + +#endif // AVR_H diff --git a/firmware/include/ccspi.h b/firmware/include/ccspi.h index 6b7bb31..a0e787e 100644 --- a/firmware/include/ccspi.h +++ b/firmware/include/ccspi.h @@ -3,6 +3,13 @@ \brief Constants for CCSPI Driver */ +#ifndef CCSPI_H +#define CCSPI_H + +#include "app.h" + +#define CCSPI 0x51 + //Chipcon SPI Commands //Grab a packet, if one is available. @@ -30,3 +37,8 @@ #define CCSPI_RXFIFO 0x3F #define CCSPI_SFLUSHRX 0x08 #define CCSPI_SFLUSHTX 0x09 + +extern app_t const ccspi_app; + +#endif // CCSPI_H + diff --git a/firmware/include/chipcon.h b/firmware/include/chipcon.h index deed945..4b01b64 100644 --- a/firmware/include/chipcon.h +++ b/firmware/include/chipcon.h @@ -3,7 +3,13 @@ \brief Chipcon application functions. */ +#ifndef CHIPCON_H +#define CHIPCON_H + #include "command.h" +#include "app.h" + +#define CHIPCON 0x30 //Chipcon command definitions. #define CCCMD_CHIP_ERASE 0x14 @@ -107,3 +113,7 @@ void cc_lockchip(); #define CC_PROGRAM_FLASH 0x98 #define CC_WIPEFLASHBUFFER 0x99 #define CC_LOCKCHIP 0x9A + +extern app_t const chipcon_app; + +#endif // CHIPCON_H diff --git a/firmware/include/command.h b/firmware/include/command.h index 567d810..dfa4003 100644 --- a/firmware/include/command.h +++ b/firmware/include/command.h @@ -4,6 +4,11 @@ */ +#ifndef COMMAND_H +#define COMMAND_H + +#include + //Types #define u8 unsigned char #define u16 unsigned int @@ -66,17 +71,10 @@ extern unsigned char silent; #define WEAKDEF #endif -//! Handle a plugin, weak-linked to error. -extern int pluginhandle(unsigned char app, - unsigned char verb, - unsigned int len) - WEAKDEF; - - //! Handle a command. Defined in goodfet.c -void handle(unsigned char app, - unsigned char verb, - unsigned long len); +void handle(uint8_t const app, + uint8_t const verb, + uint32_t const len); //! Transmit a header. void txhead(unsigned char app, unsigned char verb, @@ -127,34 +125,4 @@ void delay_us( unsigned int us ); //! Delay for specified number of clock ticks (16 MHz clock implies 62.5 ns per tick). void delay_ticks( unsigned int num_ticks ); - -void monitorhandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void spihandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void i2chandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void cchandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void jtaghandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void jtag430handle(unsigned char, unsigned char, unsigned long); -WEAKDEF void ejtaghandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void jtagarm7tdmihandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void xscalehandle(unsigned char, unsigned char, unsigned long); - -WEAKDEF void jtag430x2handle(unsigned char, unsigned char, unsigned long); - -WEAKDEF void nrfhandle(unsigned char, - unsigned char, - unsigned long); -WEAKDEF void ccspihandle(unsigned char, - unsigned char, - unsigned long); -WEAKDEF void avrhandle(unsigned char app, - unsigned char verb, - unsigned long len); -WEAKDEF int smartcardhandle(unsigned char app, - unsigned char verb, - unsigned int len); - -WEAKDEF void pichandle( unsigned char app, - unsigned char verb, - unsigned long len ); - -WEAKDEF void adchandle( unsigned char app, unsigned char verb, unsigned long len ); +#endif // COMMAND_H diff --git a/firmware/include/dspic33f.h b/firmware/include/dspic33f.h deleted file mode 100644 index be66990..0000000 --- a/firmware/include/dspic33f.h +++ /dev/null @@ -1,96 +0,0 @@ -/*! \file dspic33f.h - - \author Scott Livingston - - \brief Definitions for the dsPIC33F programmer application. Note - that the programming for dsPIC33F/PIC24H chips is - non-standard 2-wire SPI; hence, I do not use the existing - GoodFET SPI routines. - - \date March-June 2010 - -*/ - - -/*! Magic, device family specific constants (these are drawn from the - dsPIC33F/PIC24H Flash Programming Specification). Note that the - ICSP key is in bit-reversed order, since it is the only thing that - is sent MSb first (hence, we flip the bit order and use our usual - LSb-first routines). - - Per the dsPIC33F/PIC24H and PIC24F flash programming - specifications, the ICSP key is 0x4D434851. */ -#define ICSP_KEY_LOW 0xC2B2 -#define ICSP_KEY_HIGH 0x8A12 -#define APPID_ADDR 0x8007F0 - -//! I/O (pin level); follows spi.h -#define PGD BIT1 -#define PGC BIT3 -#define MCLR BIT0 - -//Handle bidirectionality of PGD -#define DIR_PGD_RD P5DIR&=~PGD -#define DIR_PGD_WR P5DIR|=PGD - -#define SET_MCLR P5OUT|=MCLR -#define CLR_MCLR P5OUT&=~MCLR -#define SET_PGD P5OUT|=PGD -#define CLR_PGD P5OUT&=~PGD -#define SET_PGC P5OUT|=PGC -#define CLR_PGC P5OUT&=~PGC - -#define READ_PGD (P5IN&PGD?1:0) - - -//! Set pins as appropriate for dsPIC33F/PIC24H -void pic33f_setup(); - -//! Start ICSP with an attached dsPIC33F/PIC24H -void pic33f_connect(); - -/*! Stop ICSP session; maybe not necessary, but cleaner since a - minimum delay is required before dropping MCLR pin after last - transmission to dsPIC33F/PIC24H chip. */ -void pic33f_disconnect(); - -//! ICSP SIX command: execute single command on attached dsPIC33F/PIC24H. -void pic33f_six( unsigned int highb, unsigned int loww ); - -//! ICSP REGOUT command: read contents of VISI register -unsigned int pic33f_regout(); - -//! Execute a list of commands on attached dsPIC33F/PIC24H. -void pic33f_sixlist( unsigned int list_len ); - -//! Start Enhanced ICSP session with dsPIC33F/PIC24H (assumes Programming Executive is present). -void pic33f_eicsp_connect(); - -/*! Get Application ID (u8), Device ID (i.e. DEVID; u16) and hardware - revision (u16). Results are dumped to the host connection (a la - txdata, app is PIC and verb is PIC_DEVID33F). - - This function assumes no ICSP (or Enhanced ICSP) session is currently open! - - Returns number of bytes written to cmddata buffer. -*/ -unsigned int pic33f_getid(); - -//! Write word -void pic33f_trans16( unsigned int word ); - -//! Write byte -void pic33f_trans8( unsigned char byte ); - - -//Command codes -#define PIC_DEVID33F 0x81 //! Read Device and Application ID -#define PIC_SIX33F 0x82 //! ICSP six command; execute instruction on target. -#define PIC_REGOUT33F 0x83 //! Read out VISI register. -#define PIC_SIXLIST33F 0x86 /* Buffers list of instructions to MSP430, - then executes them over ICSP session - with target dsPIC33F/PIC24H chip. */ - -#define PIC_RESET33F 0x87 // Reset attached dsPIC33F/PIC24H chip. -#define PIC_START33F 0x84 // Start ICSP session -#define PIC_STOP33F 0x85 // Stop ICSP (basically, drop !MCLR pin and pause briefly) diff --git a/firmware/include/ejtag.h b/firmware/include/ejtag.h index dedfc72..66044a0 100644 --- a/firmware/include/ejtag.h +++ b/firmware/include/ejtag.h @@ -3,6 +3,10 @@ \brief MIPS EJTAG IR/DR definitions */ +#ifndef EJTAG_H +#define EJTAG_H + +#define EJTAG 0x12 /* The following are standard EJTAG IR values. TCBCONTROL values, reserved values, and device-specific values have been ommitted. @@ -19,3 +23,7 @@ #define EJTAG_IR_PCSAMPLE 0x14 #define EJTAG_IR_BYPASS 0xFF +extern app_t const ejtag_app; + +#endif + diff --git a/firmware/include/glitch.h b/firmware/include/glitch.h index aef8888..b7082d8 100644 --- a/firmware/include/glitch.h +++ b/firmware/include/glitch.h @@ -3,10 +3,17 @@ \brief Glitch handler functions. */ +#ifndef GLITCH_H +#define GLITCH_H + +#include "app.h" + #include #include #include +#define GLITCH 0x71 + //Command codes #define GLITCHAPP 0x80 #define GLITCHVERB 0x81 @@ -29,7 +36,7 @@ void glitchvoltages(u16 gnd, u16 vcc); //! Set glitching rate. void glitchrate(u16 rate); -//! Handles a monitor command. -extern void glitchhandle(unsigned char app, - unsigned char verb, - unsigned long len) WEAKDEF; +extern app_t const glitch_app; + +#endif // GLITCH_H + diff --git a/firmware/include/i2c.h b/firmware/include/i2c.h new file mode 100644 index 0000000..5c41c60 --- /dev/null +++ b/firmware/include/i2c.h @@ -0,0 +1,16 @@ +/*! \file i2c.h + \author Dave Huseby + \brief i2c bus protocol functions. +*/ + +#ifndef I2C_H +#define I2C_H + +#include "app.h" + +#define I2C 0x02 + +extern app_t const i2c_app; + +#endif + diff --git a/firmware/include/jtag.h b/firmware/include/jtag.h index 2d09c2c..5735a95 100644 --- a/firmware/include/jtag.h +++ b/firmware/include/jtag.h @@ -6,10 +6,9 @@ #ifndef JTAG_H #define JTAG_H -#include -#include -#include +#include "app.h" +#define JTAG 0x10 // Generic Commands @@ -101,9 +100,7 @@ extern int savedtclk; #define NOEND 2 #define NORETIDLE 4 - //JTAG430 commands -//#include "jtag430.h" #define Exit2_DR 0x0 #define Exit_DR 0x1 #define Shift_DR 0x2 @@ -120,5 +117,7 @@ extern int savedtclk; #define Update_IR 0xd #define Capture_IR 0xe #define Test_Reset 0xf - + +extern app_t const jtag_app; + #endif diff --git a/firmware/include/jtag430.h b/firmware/include/jtag430.h index 7d38bc7..91c4eba 100644 --- a/firmware/include/jtag430.h +++ b/firmware/include/jtag430.h @@ -3,9 +3,14 @@ \brief JTAG handler functions. */ +#ifndef JTAG430_H +#define JTAG430_H +#include "app.h" #include "jtag.h" +#define JTAG430 0x11 + extern unsigned int drwidth; #define MSP430MODE 0 @@ -96,3 +101,7 @@ void jtag430_por(); #define JTAG430_ERASEINFO 0xE8 #define JTAG430_COREIP_ID 0xF0 #define JTAG430_DEVICE_ID 0xF1 + +extern app_t const jtag430_app; + +#endif // JTAG430_H diff --git a/firmware/include/jtagarm7.h b/firmware/include/jtagarm7.h index 3c59555..ea13851 100644 --- a/firmware/include/jtagarm7.h +++ b/firmware/include/jtagarm7.h @@ -2,22 +2,16 @@ \brief JTAG handler functions for the ARM7TDMI family of processors */ -#include "jtag.h" +#ifndef JTAGARM7_H +#define JTAGARM7_H +#include "app.h" + +#define JTAGARM7 0x13 #define JTAGSTATE_ARM 0 // bit 4 on dbg status reg is low #define JTAGSTATE_THUMB 1 -unsigned long last_instr = -1; -unsigned char last_sysstate = 0; -unsigned char last_ir = -1; -unsigned char last_scanchain = -1; -unsigned char tapstate = 15; -unsigned char current_dbgstate = -1; -//unsigned char last_halt_debug_state = -1; -//unsigned long last_halt_pc = -1; - - // JTAGARM7 Commands //! Start JTAG @@ -145,3 +139,7 @@ The least significant bit of the instruction register is scanned in and scanned #define JTAG_ARM7TDMI_DBG_cgenL 8 #define JTAG_ARM7TDMI_DBG_TBIT 16 +extern app_t const jtagarm7_app; + +#endif // JTAGARM7_H + diff --git a/firmware/include/jtagxscale.h b/firmware/include/jtagxscale.h index f1f17fa..57973ba 100644 --- a/firmware/include/jtagxscale.h +++ b/firmware/include/jtagxscale.h @@ -7,6 +7,13 @@ /* NOTE: I heavily cribbed from the ARM7TDMI jtag implementation. Credit where * credit is due. */ +#ifndef JTAGXSCALE_H +#define JTAGXSCALE_H + +#include "app.h" + +#define JTAGXSCALE 0x15 + /* * Utility Macros */ @@ -81,4 +88,7 @@ unsigned long jtag_xscale_shift_n(unsigned long word, * out the TDO and return it. */ unsigned long jtag_xscale_idcode(); +extern app_t const jtagxscale_app; + +#endif // JTAGXSCALE_H diff --git a/firmware/include/monitor.h b/firmware/include/monitor.h index a4a3156..d38dae9 100644 --- a/firmware/include/monitor.h +++ b/firmware/include/monitor.h @@ -3,22 +3,18 @@ \brief Debug monitor commands. */ -#ifdef MSP430 -#include -#include -#include -#endif +#ifndef MONITOR_H +#define MONITOR_H -// Generic Commands +#include "app.h" -//! Overwrite all of RAM with 0xBEEF, then reboot. -void monitor_ram_pattern(); -//! Return the number of contiguous bytes 0xBEEF, to measure RAM usage. -unsigned int monitor_ram_depth(); +// Montir app number +#define MONITOR 0x00 // Monitor Commands #define MONITOR_CHANGE_BAUD 0x80 #define MONITOR_ECHO 0x81 +#define MONITOR_LIST_APPS 0x82 #define MONITOR_RAM_PATTERN 0x90 #define MONITOR_RAM_DEPTH 0x91 @@ -33,4 +29,7 @@ unsigned int monitor_ram_depth(); #define MONITOR_WRITEBUF 0xC1 #define MONITOR_SIZEBUF 0xC2 +extern app_t const monitor_app; + +#endif // MONITOR_H diff --git a/firmware/include/nrf.h b/firmware/include/nrf.h index 2423495..bf0f99d 100644 --- a/firmware/include/nrf.h +++ b/firmware/include/nrf.h @@ -3,6 +3,13 @@ \brief Constants for NRF Driver */ +#ifndef NRF_H +#define NRF_H + +#include "app.h" + +#define NRF 0x50 + //Nordic RF Commands //Grab a packet, if one is available. @@ -57,6 +64,7 @@ //Also 32-byte buffers for ACK_PLD, TX_PLD, and RX_PLD. //Separate SPI commands. +extern app_t const nrf_app; - +#endif // NRF_H diff --git a/firmware/include/pic.h b/firmware/include/pic.h new file mode 100644 index 0000000..e95c054 --- /dev/null +++ b/firmware/include/pic.h @@ -0,0 +1,106 @@ +/*! \file dspic33f.h + + \author Scott Livingston + + \brief Definitions for the dsPIC33F programmer application. Note + that the programming for dsPIC33F/PIC24H chips is + non-standard 2-wire SPI; hence, I do not use the existing + GoodFET SPI routines. + + \date March-June 2010 + +*/ + +#ifndef PIC_H +#define PIC_H + +#include "app.h" + +#define PIC 0x34 + +/*! Magic, device family specific constants (these are drawn from the + dsPIC33F/PIC24H Flash Programming Specification). Note that the + ICSP key is in bit-reversed order, since it is the only thing that + is sent MSb first (hence, we flip the bit order and use our usual + LSb-first routines). + + Per the dsPIC33F/PIC24H and PIC24F flash programming + specifications, the ICSP key is 0x4D434851. */ +#define ICSP_KEY_LOW 0xC2B2 +#define ICSP_KEY_HIGH 0x8A12 +#define APPID_ADDR 0x8007F0 + +//! I/O (pin level); follows spi.h +#define PGD BIT1 +#define PGC BIT3 +#define MCLR BIT0 + +//Handle bidirectionality of PGD +#define DIR_PGD_RD P5DIR&=~PGD +#define DIR_PGD_WR P5DIR|=PGD + +#define SET_MCLR P5OUT|=MCLR +#define CLR_MCLR P5OUT&=~MCLR +#define SET_PGD P5OUT|=PGD +#define CLR_PGD P5OUT&=~PGD +#define SET_PGC P5OUT|=PGC +#define CLR_PGC P5OUT&=~PGC + +#define READ_PGD (P5IN&PGD?1:0) + + +//! Set pins as appropriate for dsPIC33F/PIC24H +void pic33f_setup(); + +//! Start ICSP with an attached dsPIC33F/PIC24H +void pic33f_connect(); + +/*! Stop ICSP session; maybe not necessary, but cleaner since a + minimum delay is required before dropping MCLR pin after last + transmission to dsPIC33F/PIC24H chip. */ +void pic33f_disconnect(); + +//! ICSP SIX command: execute single command on attached dsPIC33F/PIC24H. +void pic33f_six( unsigned int highb, unsigned int loww ); + +//! ICSP REGOUT command: read contents of VISI register +unsigned int pic33f_regout(); + +//! Execute a list of commands on attached dsPIC33F/PIC24H. +void pic33f_sixlist( unsigned int list_len ); + +//! Start Enhanced ICSP session with dsPIC33F/PIC24H (assumes Programming Executive is present). +void pic33f_eicsp_connect(); + +/*! Get Application ID (u8), Device ID (i.e. DEVID; u16) and hardware + revision (u16). Results are dumped to the host connection (a la + txdata, app is PIC and verb is PIC_DEVID33F). + + This function assumes no ICSP (or Enhanced ICSP) session is currently open! + + Returns number of bytes written to cmddata buffer. +*/ +unsigned int pic33f_getid(); + +//! Write word +void pic33f_trans16( unsigned int word ); + +//! Write byte +void pic33f_trans8( unsigned char byte ); + + +//Command codes +#define PIC_DEVID33F 0x81 //! Read Device and Application ID +#define PIC_SIX33F 0x82 //! ICSP six command; execute instruction on target. +#define PIC_REGOUT33F 0x83 //! Read out VISI register. +#define PIC_SIXLIST33F 0x86 /* Buffers list of instructions to MSP430, + then executes them over ICSP session + with target dsPIC33F/PIC24H chip. */ + +#define PIC_RESET33F 0x87 // Reset attached dsPIC33F/PIC24H chip. +#define PIC_START33F 0x84 // Start ICSP session +#define PIC_STOP33F 0x85 // Stop ICSP (basically, drop !MCLR pin and pause briefly) + +extern app_t const pic_app; + +#endif // PIC_H diff --git a/firmware/include/platform.h b/firmware/include/platform.h index 134a082..a9f9ebc 100644 --- a/firmware/include/platform.h +++ b/firmware/include/platform.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "config.h" diff --git a/firmware/include/ps2.h b/firmware/include/ps2.h index 8b13789..eecdd13 100644 --- a/firmware/include/ps2.h +++ b/firmware/include/ps2.h @@ -1 +1,16 @@ +/*! \file ps2.h + \author Dave Huseby + \brief PS2 Timing Monitor for GoodFET +*/ + +#ifndef PS2_H +#define PS2_H + +#include "app.h" + +#define PS2 0x72 + +extern app_t const ps2_app; + +#endif diff --git a/firmware/include/smartcard.h b/firmware/include/smartcard.h new file mode 100644 index 0000000..83db050 --- /dev/null +++ b/firmware/include/smartcard.h @@ -0,0 +1,16 @@ +/*! \file smartcard.h + \author Dave Huseby + \brief adds support for communicating with smart cards and sim cards. +*/ + +#ifndef SMARTCARD_H +#define SMARTCARD_H + +#include "app.h" + +#define SMARTCARD 0x73 + +extern app_t const smartcard_app; + +#endif + diff --git a/firmware/include/spi.h b/firmware/include/spi.h index 590db0e..dfbb28a 100644 --- a/firmware/include/spi.h +++ b/firmware/include/spi.h @@ -3,6 +3,12 @@ \brief Definitions for the SPI application. */ +#ifndef SPI_H +#define SPI_H + +#include "app.h" + +#define SPI 0x01 //Pins and I/O //#define SS BIT0 @@ -21,7 +27,6 @@ #define SETRST P2OUT|=RST #define CLRRST P2OUT&=~RST - //! Set up the pins for SPI mode. void spisetup(); @@ -49,3 +54,7 @@ unsigned char spitrans8(unsigned char byte); unsigned char spiflash_status(); //! Erase a sector. void spiflash_erasesector(unsigned long adr); + +extern app_t const spi_app; + +#endif