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();
--- /dev/null
+#!/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
+
+
#!/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
# 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):
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
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();
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();
# 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:
# Miscelaneous:
# glitch -- Glitch research tool
# smartcard -- Smartcard IO
+# ps2 -- PS2 spy
# Configurations
# 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
# 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
# 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
# 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
# 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
# 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
false
config:
cp platforms/$(platform).h include/config.h
+appsfiles:
+ ./gen_apps $(hdrs)
+err:;$(ERR)
+builddate:
+ ./gen_builddate_h
goodfet.hex: goodfet
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
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
\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()
{
//! 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;
#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(){
}
//! 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;
/*
//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<len;i++){
+ txhead(app,verb,l);
+ for(i=0;i<l;i++){
serial_tx(avr_peekflash(at++));
}
break;
#include <io.h>
#include <iomacros.h>
+//! 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
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();
#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(){
}
//! 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],
#include "platform.h"
#include "command.h"
+#include "i2c.h"
#include <signal.h>
#include <io.h>
//Pins and I/O
#include <jtag.h>
+
+//! 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
}
-//! 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<len;i++)
- cmddata[i]=I2C_Read(1); //Always acknowledge
- txdata(app,verb,len);
- break;
- case WRITE:
- cmddata[0]=0;
- for(i=0;i<len;i++)
- cmddata[0]+=I2C_Write(cmddata[i]);
- txdata(app,verb,1);
- break;
- case START:
- I2C_Start();
- txdata(app,verb,0);
- break;
- case STOP:
- I2C_Stop();
- txdata(app,verb,0);
- break;
- case SETUP:
- I2C_Init();
- txdata(app,verb,0);
- break;
- }
+//! Handles an i2c command.
+void i2c_handle_fn( uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len)
+{
+ unsigned char i;
+ unsigned long l;
+ switch(verb)
+ {
+
+ case PEEK:
+ break;
+ case POKE:
+ break;
+
+ case READ:
+ l = len;
+ if(l > 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;i<len;i++)
+ cmddata[0]+=I2C_Write(cmddata[i]);
+ txdata(app,verb,1);
+ break;
+ case START:
+ I2C_Start();
+ txdata(app,verb,0);
+ break;
+ case STOP:
+ I2C_Stop();
+ txdata(app,verb,0);
+ break;
+ case SETUP:
+ I2C_Init();
+ txdata(app,verb,0);
+ break;
+ }
}
#include "platform.h"
#include "command.h"
#include "jtag.h"
+#include "ejtag.h"
//! Handles MIPS EJTAG commands. Forwards others to JTAG.
-void ejtaghandle(unsigned char app,
- unsigned char verb,
- unsigned long len){
-
- switch(verb){
- case START:
- cmddata[0]=jtag_ir_shift8(IR_BYPASS);
- txdata(app,verb,1);
- break;
- case STOP:
- txdata(app,verb,0);
- break;
- case PEEK:
- //WRITEME
- case POKE:
- //WRITEME
- default:
- jtaghandle(app,verb,len);
- }
+void ejtag_handle_fn( uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len);
+
+// define the ejtag app's app_t
+app_t const ejtag_app = {
+
+ /* app number */
+ EJTAG,
+
+ /* handle fn */
+ ejtag_handle_fn,
+
+ /* name */
+ "EJTAG",
+
+ /* desc */
+ "\tThe EJTAG app extends the basic JTAG app with support\n"
+ "\tfor JTAG'ing MIPS based devices.\n"
+};
+
+//! Handles MIPS EJTAG commands. Forwards others to JTAG.
+void ejtag_handle_fn( uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len)
+{
+ switch(verb)
+ {
+ case START:
+ cmddata[0] = jtag_ir_shift8(EJTAG_IR_BYPASS);
+ txdata(app, verb, 1);
+ break;
+ case STOP:
+ txdata(app,verb,0);
+ break;
+ case PEEK:
+ //WRITEME
+ case POKE:
+ //WRITEME
+ default:
+ (*(ejtag_app.handle))(app, verb, len);
+ }
}
#include "command.h"
#include "jtag.h"
+#define JTAG_APP
+
+//! Handles a monitor command.
+void jtag_handle_fn(uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len);
+
+// define the jtag app's app_t
+app_t const jtag_app = {
+
+ /* app number */
+ JTAG,
+
+ /* handle fn */
+ jtag_handle_fn,
+
+ /* name */
+ "JTAG",
+
+ /* desc */
+ "\tThe JTAG app handles basic JTAG operations such as\n"
+ "\tresetting the TAP, resetting the target, detecting\n"
+ "\tthe instruction register width, shifting bits into\n"
+ "\tboth the instruction and data registers.\n"
+};
+
//! Set up the pins for JTAG mode.
void jtagsetup(){
int savedtclk=0;
-// NOTE: important: THIS MODULE REVOLVES AROUND RETURNING TO RUNTEST/IDLE, OR THE FUNCTIONAL EQUIVALENT
-//! Shift N bits over TDI/TDO. May choose LSB or MSB, and select whether to terminate (TMS-high on last bit) and whether to return to RUNTEST/IDLE
+// NOTE: important: THIS MODULE REVOLVES AROUND RETURNING TO RUNTEST/IDLE, OR
+// THE FUNCTIONAL EQUIVALENT
+//! Shift N bits over TDI/TDO. May choose LSB or MSB, and select whether to
+// terminate (TMS-high on last bit) and whether to return to RUNTEST/IDLE
// flags should be 0 for most uses.
// for the extreme case, flags should be (NOEND|NORETDLE|LSB)
// other edge cases can involve a combination of those three flags
//
// the max bit-size that can be be shifted is 32-bits.
-// for longer shifts, use the NOEND flag (which infers NORETIDLE so the additional flag is unnecessary)
+// for longer shifts, use the NOEND flag (which infers NORETIDLE so the
+// additional flag is unnecessary)
//
-// NORETIDLE is used for special cases where (as with arm) the debug subsystem does not want to
-// return to the RUN-TEST/IDLE state between setting IR and DR
-unsigned long jtagtransn(unsigned long word, unsigned char bitcount, unsigned char flags){
+// NORETIDLE is used for special cases where (as with arm) the debug
+// subsystem does not want to return to the RUN-TEST/IDLE state between
+// setting IR and DR
+unsigned long jtagtransn(unsigned long word,
+ unsigned char bitcount,
+ unsigned char flags) {
unsigned char bit;
unsigned long high = 1L;
unsigned long mask;
}
//! Handles a monitor command.
-void jtaghandle(unsigned char app,
- unsigned char verb,
- unsigned long len){
- switch(verb){
- //START handled by specific JTAG
- case STOP:
- jtag_stop();
- txdata(app,verb,0);
- break;
- case SETUP:
- jtagsetup();
- txdata(app,verb,0);
- break;
- case JTAG_IR_SHIFT:
- cmddata[0]=jtag_ir_shift8(cmddata[0]);
- txdata(app,verb,1);
- break;
- case JTAG_DR_SHIFT:
- cmddataword[0]=jtag_dr_shift16(cmddataword[0]);
- txdata(app,verb,2);
- break;
- case JTAG_RESETTAP:
- jtag_resettap();
- txdata(app,verb,0);
- break;
- default:
- txdata(app,NOK,0);
- }
+void jtag_handle_fn(uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len)
+{
+ switch(verb)
+ {
+ //START handled by specific JTAG
+ case STOP:
+ jtag_stop();
+ txdata(app,verb,0);
+ break;
+
+ case SETUP:
+ jtagsetup();
+ txdata(app,verb,0);
+ break;
+
+ case JTAG_IR_SHIFT:
+ cmddata[0]=jtag_ir_shift8(cmddata[0]);
+ txdata(app,verb,1);
+ break;
+
+ case JTAG_DR_SHIFT:
+ cmddataword[0]=jtag_dr_shift16(cmddataword[0]);
+ txdata(app,verb,2);
+ break;
+
+ case JTAG_RESETTAP:
+ jtag_resettap();
+ txdata(app,verb,0);
+ break;
+
+ default:
+ txdata(app,NOK,0);
+ }
}
#include "command.h"
#include "jtag430.h"
+//! Handles classic MSP430 JTAG commands. Forwards others to JTAG.
+void jtag430_handle_fn(uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len);
+
+// define the jtag430 app's app_t
+app_t const jtag430_app = {
+
+ /* app number */
+ JTAG430,
+
+ /* handle fn */
+ jtag430_handle_fn,
+
+ /* name */
+ "JTAG430",
+
+ /* desc */
+ "\tThe JTAG430 app adds to the basic JTAG app\n"
+ "\tsupport for JTAG'ing MSP430 devices.\n"
+};
unsigned int jtag430mode=MSP430X2MODE;
//! Handles classic MSP430 JTAG commands. Forwards others to JTAG.
-void jtag430handle(unsigned char app,
- unsigned char verb,
- unsigned long len){
- unsigned long at;
+void jtag430_handle_fn(uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len)
+{
+ unsigned long at, l;
unsigned int i, val;
//Fetch large blocks for bulk fetches,
//small blocks for individual peeks.
if(len>5)
- 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<len;i+=2){
+ txhead(app,verb,l);
+ for(i = 0; i < l; i += 2) {
jtag430_resettap();
val=jtag430_readmem(at);
break;
default:
- jtaghandle(app,verb,len);
+ (*(jtag_app.handle))(app,verb,len);
}
//jtag430_resettap(); //DO NOT UNCOMMENT
}
#include "platform.h"
#include "command.h"
+#include "jtag.h"
#include "jtagarm7.h"
+//! Handles ARM7TDMI JTAG commands. Forwards others to JTAG.
+void jtagarm7_handle_fn( uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len);
+
+// define the jtagarm7 app's app_t
+app_t const jtagarm7_app = {
+
+ /* app number */
+ JTAGARM7,
+
+ /* handle fn */
+ jtagarm7_handle_fn,
+
+ /* name */
+ "JTAGARM7",
+
+ /* desc */
+ "\tThe JTAGARM7 app extends the basic JTAG app with support\n"
+ "\tfor JTAG'ing ARM7TDMI based devices.\n"
+};
+
+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;
/**** 20-pin Connection Information (pin1 is on top-right for both connectors)****
GoodFET -> 7TDMI 20-pin connector (HE-10 connector)
///////////////////////////////////////////////////////////////////////////////////////////////////
//! 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){
case JTAGARM7_CHIP_ERASE:
*/
default:
- jtaghandle(app,verb,len);
+ (*(jtag_app.handle))(app,verb,len);
}
}
#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
}
/* 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)
{
#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();
+}
+
+
+++ /dev/null
-/*! \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;
-}
--- /dev/null
+/*! \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;
+}
#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;
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
#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
}
//! 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.
#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
}
//! 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.
#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
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();
debugstr("Unknown smartcard verb.");
txdata(app,NOK,0);
}
- return 0;
}
#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
}
//! 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<len;i++)
- cmddata[i]=spitrans8(cmddata[i]);
- SETSS; //Raise !SS to end transaction.
- txdata(app,verb,len);
- break;
-
- case SPI_RW_EM260: //SPI exchange with an EM260
- spi_rw_em260(app,verb,len);
- break;
-
- case SPI_JEDEC://Grab 3-byte JEDEC ID.
- CLRSS; //Drop !SS to begin transaction.
- spitrans8(0x9f);
- len=3; //Length is variable in some chips, 3 minimum.
- for(i=0;i<len;i++)
- cmddata[i]=spitrans8(cmddata[i]);
- txdata(app,verb,len);
- SETSS; //Raise !SS to end transaction.
- break;
-
- case PEEK://Grab 128 bytes from an SPI Flash ROM
- spiflash_peek(app,verb,len);
- break;
-
-
- case POKE://Poke up bytes from an SPI Flash ROM.
- spiflash_pokeblocks(cmddatalong[0],//adr
- cmddata+4,//buf
- len-4);//len
-
- txdata(app,verb,0);
- break;
-
-
- case SPI_ERASE://Erase the SPI Flash ROM.
- spiflash_wrten();
- CLRSS; //Drop !SS to begin transaction.
- spitrans8(0xC7);//Chip Erase
- SETSS; //Raise !SS to end transaction.
-
-
- while(spiflash_status()&0x01)//while busy
- PLEDOUT^=PLEDPIN;
- PLEDOUT&=~PLEDPIN;
-
- txdata(app,verb,0);
- break;
-
- case SETUP:
- spisetup();
- txdata(app,verb,0);
- break;
- }
-
+void spi_handle_fn( uint8_t const app,
+ uint8_t const verb,
+ uint32_t const len)
+{
+ unsigned long i, l;
+
+ //Raise !SS to end transaction, just in case we forgot.
+ SETSS;
+ //spisetup();
+
+ switch(verb)
+ {
+ case READ:
+ case WRITE:
+ CLRSS; //Drop !SS to begin transaction.
+ for(i=0;i<len;i++)
+ cmddata[i]=spitrans8(cmddata[i]);
+ SETSS; //Raise !SS to end transaction.
+ txdata(app,verb,len);
+ break;
+
+ case SPI_RW_EM260: //SPI exchange with an EM260
+ spi_rw_em260(app,verb,len);
+ break;
+
+ case SPI_JEDEC://Grab 3-byte JEDEC ID.
+ CLRSS; //Drop !SS to begin transaction.
+ spitrans8(0x9f);
+ l=3; //Length is variable in some chips, 3 minimum.
+ for(i = 0; i < l; i++)
+ cmddata[i]=spitrans8(cmddata[i]);
+ txdata(app,verb,len);
+ SETSS; //Raise !SS to end transaction.
+ break;
+
+ case PEEK://Grab 128 bytes from an SPI Flash ROM
+ spiflash_peek(app,verb,len);
+ break;
+
+ case POKE://Poke up bytes from an SPI Flash ROM.
+ spiflash_pokeblocks(cmddatalong[0],//adr
+ cmddata+4,//buf
+ len-4);//len
+ txdata(app,verb,0);
+ break;
+
+ case SPI_ERASE://Erase the SPI Flash ROM.
+ spiflash_wrten();
+ CLRSS; //Drop !SS to begin transaction.
+ spitrans8(0xC7);//Chip Erase
+ SETSS; //Raise !SS to end transaction.
+
+ while(spiflash_status()&0x01)//while busy
+ PLEDOUT^=PLEDPIN;
+ PLEDOUT&=~PLEDPIN;
+
+ txdata(app,verb,0);
+ break;
+
+ case SETUP:
+ spisetup();
+ txdata(app,verb,0);
+ break;
+ }
}
--- /dev/null
+#!/usr/bin/env python
+
+import sys
+
+def main():
+ fout = open("include/apps.h", "w+")
+ print >> 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 <stdint.h>"
+ 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())
--- /dev/null
+#!/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())
#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<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);
- }
- }
+ //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 < 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);
+ }
+ }
}
\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();
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
+
--- /dev/null
+/*! \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
+
+++ /dev/null
-/*! \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
\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();
#define AVR_READCAL 0x85
//! Bulk load data
#define AVR_BULKLOAD 0x86
+
+extern app_t const avr_app;
+
+#endif // AVR_H
\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.
#define CCSPI_RXFIFO 0x3F
#define CCSPI_SFLUSHRX 0x08
#define CCSPI_SFLUSHTX 0x09
+
+extern app_t const ccspi_app;
+
+#endif // CCSPI_H
+
\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
#define CC_PROGRAM_FLASH 0x98
#define CC_WIPEFLASHBUFFER 0x99
#define CC_LOCKCHIP 0x9A
+
+extern app_t const chipcon_app;
+
+#endif // CHIPCON_H
*/
+#ifndef COMMAND_H
+#define COMMAND_H
+
+#include <stdint.h>
+
//Types
#define u8 unsigned char
#define u16 unsigned int
#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,
//! 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
+++ /dev/null
-/*! \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)
\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.
#define EJTAG_IR_PCSAMPLE 0x14
#define EJTAG_IR_BYPASS 0xFF
+extern app_t const ejtag_app;
+
+#endif
+
\brief Glitch handler functions.
*/
+#ifndef GLITCH_H
+#define GLITCH_H
+
+#include "app.h"
+
#include <signal.h>
#include <io.h>
#include <iomacros.h>
+#define GLITCH 0x71
+
//Command codes
#define GLITCHAPP 0x80
#define GLITCHVERB 0x81
//! 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
+
--- /dev/null
+/*! \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
+
#ifndef JTAG_H
#define JTAG_H
-#include <signal.h>
-#include <io.h>
-#include <iomacros.h>
+#include "app.h"
+#define JTAG 0x10
// Generic Commands
#define NOEND 2
#define NORETIDLE 4
-
//JTAG430 commands
-//#include "jtag430.h"
#define Exit2_DR 0x0
#define Exit_DR 0x1
#define Shift_DR 0x2
#define Update_IR 0xd
#define Capture_IR 0xe
#define Test_Reset 0xf
-
+
+extern app_t const jtag_app;
+
#endif
\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
#define JTAG430_ERASEINFO 0xE8
#define JTAG430_COREIP_ID 0xF0
#define JTAG430_DEVICE_ID 0xF1
+
+extern app_t const jtag430_app;
+
+#endif // JTAG430_H
\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
#define JTAG_ARM7TDMI_DBG_cgenL 8
#define JTAG_ARM7TDMI_DBG_TBIT 16
+extern app_t const jtagarm7_app;
+
+#endif // JTAGARM7_H
+
/* 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
*/
* out the TDO and return it. */
unsigned long jtag_xscale_idcode();
+extern app_t const jtagxscale_app;
+
+#endif // JTAGXSCALE_H
\brief Debug monitor commands.
*/
-#ifdef MSP430
-#include <signal.h>
-#include <io.h>
-#include <iomacros.h>
-#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
#define MONITOR_WRITEBUF 0xC1
#define MONITOR_SIZEBUF 0xC2
+extern app_t const monitor_app;
+
+#endif // MONITOR_H
\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.
//Also 32-byte buffers for ACK_PLD, TX_PLD, and RX_PLD.
//Separate SPI commands.
+extern app_t const nrf_app;
-
+#endif // NRF_H
--- /dev/null
+/*! \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
#include <signal.h>
#include <io.h>
#include <iomacros.h>
+#include <stdint.h>
#include "config.h"
+/*! \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
--- /dev/null
+/*! \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
+
\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
#define SETRST P2OUT|=RST
#define CLRRST P2OUT&=~RST
-
//! Set up the pins for SPI mode.
void spisetup();
unsigned char spiflash_status();
//! Erase a sector.
void spiflash_erasesector(unsigned long adr);
+
+extern app_t const spi_app;
+
+#endif