X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Fchipcon%2Fchipcon.c;h=28440c48e36718c1cd7ca65aa4c87b9014791d3b;hp=49aa7d8b6e27a95c6171c9e0bdb6012bb7d46834;hb=1265496073840b32e1e57b8b23f2d4de4bcb78c4;hpb=2578d3d26d4b79f281f46ca36faf6d0c67edbace diff --git a/firmware/apps/chipcon/chipcon.c b/firmware/apps/chipcon/chipcon.c index 49aa7d8..28440c4 100644 --- a/firmware/apps/chipcon/chipcon.c +++ b/firmware/apps/chipcon/chipcon.c @@ -1,17 +1,16 @@ -//GoodFET ChipCon Debugging Application -//Handles basic I/O for the Chipcon 8051 debugging protocol. +/*! \file chipcon.c + \author Travis Goodspeed + \brief Chipcon 8051 debugging. +*/ -//Higher level left to client application. //This is like SPI, except that you read or write, not both. -/** N.B. The READ verb performs a write of all (any) supplied data, +/* N.B. The READ verb performs a write of all (any) supplied data, then reads a single byte reply from the target. The WRITE verb only writes. */ -//This is REALLY untested. - #include "platform.h" #include "command.h" #include "chipcon.h" @@ -21,7 +20,7 @@ #include -/** Concerning clock rates, +/* Concerning clock rates, the maximimum clock rates are defined on page 4 of the spec. They vary, but are roughly 30MHz. Raising this clock rate might allow for clock glitching, but the GoodFET isn't sufficient fast for that. @@ -37,7 +36,7 @@ //This could be more accurate. //Does it ever need to be? -#define CCSPEED 0 +#define CCSPEED 3 #define CCDELAY(x) delay(x) #define SETMOSI P5OUT|=MOSI @@ -125,9 +124,12 @@ void ccread(unsigned char len){ //! Handles a monitor command. void cchandle(unsigned char app, unsigned char verb, - unsigned char len){ + unsigned long len){ + //Always init. Might help with buggy lines. + ccdebuginit(); + switch(verb){ - //PEEK and POKE will come later. + //CC_PEEK and CC_POKE will come later. case READ: //Write a command and return 1-byte reply. cccmd(len); ccread(1); @@ -168,7 +170,7 @@ void cchandle(unsigned char app, break; case CC_GET_PC: cc_get_pc(); - txdata(app,verb,1); + txdata(app,verb,2); break; case CC_READ_STATUS: cc_read_status(); @@ -187,7 +189,8 @@ void cchandle(unsigned char app, txdata(app,verb,1); break; case CC_DEBUG_INSTR: - txdata(app,NOK,0);//TODO add me + cc_debug_instr(len); + txdata(app,verb,1); break; case CC_STEP_INSTR: cc_step_instr(); @@ -204,8 +207,17 @@ void cchandle(unsigned char app, //Macro commands case CC_READ_CODE_MEMORY: + cmddata[0]=cc_peekcodebyte(cmddataword[0]); + txdata(app,verb,1); + break; case CC_READ_XDATA_MEMORY: + cmddata[0]=cc_peekdatabyte(cmddataword[0]); + txdata(app,verb,1); + break; case CC_WRITE_XDATA_MEMORY: + cmddata[0]=cc_pokedatabyte(cmddataword[0], cmddata[2]); + txdata(app,verb,1); + break; case CC_SET_PC: case CC_CLOCK_INIT: case CC_WRITE_FLASH_PAGE: @@ -271,7 +283,6 @@ unsigned short cc_get_pc(){ return cmddataword[0]; } - //! Set a hardware breakpoint. void cc_set_hw_brkpnt(unsigned short adr){ cmddataword[0]=adr; @@ -304,3 +315,111 @@ void cc_step_instr(){ ccread(1); return; } + +//! Debug an instruction. +void cc_debug_instr(unsigned char len){ + //Bottom two bits of command indicate length. + unsigned char cmd=0x54+(len&0x3); + CCWRITE; + cctrans8(cmd); //Second command code + cccmd(len&0x3); //Command itself. + ccread(1); + return; +} + +//! Debug an instruction, for local use. +unsigned char cc_debug(unsigned char len, + unsigned char a, + unsigned char b, + unsigned char c){ + unsigned char cmd=0x54+(len&0x3);//(len&0x3); + CCWRITE; + cctrans8(0xFF);//resync + cctrans8(0xFF);//resync + cctrans8(0xFF);//resync + cctrans8(0xFF);//resync + cctrans8(0xFF);//resync + cctrans8(cmd); + if(len--) + cctrans8(a); + if(len--) + cctrans8(b); + if(len--) + cctrans8(c); + CCREAD; + return cctrans8(0x00); +} + +//! Fetch a byte of code memory. +unsigned char cc_peekcodebyte(unsigned long adr){ + /** See page 9 of SWRA124 */ + unsigned char bank=adr>>15, + lb=adr&0xFF, + hb=(adr>>8)&0x7F, + toret=0; + adr&=0x7FFF; + + //MOV MEMCTR, (bank*16)+1 + cc_debug(3, 0x75, 0xC7, (bank<<4) + 1); + //MOV DPTR, address + cc_debug(3, 0x90, hb, lb); + + //for each byte + //CLR A + cc_debug(2, 0xE4, 0, 0); + //MOVC A, @A+DPTR; + toret=cc_debug(3, 0x93, 0, 0); + //INC DPTR + //cc_debug(1, 0xA3, 0, 0); + + return toret; +} + + +//! Set a byte of data memory. +unsigned char cc_pokedatabyte(unsigned int adr, + unsigned char val){ + unsigned char + hb=(adr&0xFF00)>>8, + lb=adr&0xFF; + + //MOV DPTR, adr + cc_debug(3, 0x90, hb, lb); + //MOV A, val + cc_debug(2, 0x74, val, 0); + //MOVX @DPTR, A + cc_debug(1, 0xF0, 0, 0); + + return 0; + /* +DEBUG_INSTR(IN: 0x90, HIBYTE(address), LOBYTE(address), OUT: Discard); +for (n = 0; n < count; n++) { + DEBUG_INSTR(IN: 0x74, inputArray[n], OUT: Discard); + DEBUG_INSTR(IN: 0xF0, OUT: Discard); + DEBUG_INSTR(IN: 0xA3, OUT: Discard); +} + */ +} + +//! Fetch a byte of data memory. +unsigned char cc_peekdatabyte(unsigned int adr){ + unsigned char + hb=(adr&0xFF00)>>8, + lb=adr&0xFF, + toret; + + //MOV DPTR, adr + cc_debug(3, 0x90, hb, lb); + //MOVX A, @DPTR + //Must be 2, perhaps for clocking? + toret=cc_debug(3, 0xE0, 0, 0); + return toret; + + /* +DEBUG_INSTR(IN: 0x90, HIBYTE(address), LOBYTE(address), OUT: Discard); +for (n = 0; n < count; n++) { + DEBUG_INSTR(IN: 0xE0, OUT: outputArray[n]); + DEBUG_INSTR(IN: 0xA3, OUT: Discard); +} + */ +}