From 64742f14268508206da9d46480282a045de9a693 Mon Sep 17 00:00:00 2001 From: travisutk Date: Sat, 17 Oct 2009 08:57:34 +0000 Subject: [PATCH] Working toward support for writing flash on Chipcon. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@201 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- client/GoodFETCC.py | 7 ++- client/goodfet.cc | 4 ++ firmware/apps/chipcon/chipcon.c | 93 ++++++++++++++++++++++++++++++++- firmware/include/chipcon.h | 18 +++++++ 4 files changed, 119 insertions(+), 3 deletions(-) diff --git a/client/GoodFETCC.py b/client/GoodFETCC.py index d171f86..96e9c60 100644 --- a/client/GoodFETCC.py +++ b/client/GoodFETCC.py @@ -114,9 +114,9 @@ class GoodFETCC(GoodFET): return ord(self.data[0]) CCstatusbits={0x80 : "erased", 0x40 : "pcon_idle", - 0x20 : "halted", + 0x20 : "cpu_halted", 0x10 : "pm0", - 0x08 : "halted", + 0x08 : "halt_status", 0x04 : "locked", 0x02 : "oscstable", 0x01 : "overflow"}; @@ -146,4 +146,7 @@ class GoodFETCC(GoodFET): def CCstep_instr(self): """Step one instruction.""" self.writecmd(0x30,0x89,0,self.data); + def CCflashpage(self,adr): + """Flash a page of flash from 0xF000 in XDATA""" + self.writecmd(0x30,0x95,4,data); diff --git a/client/goodfet.cc b/client/goodfet.cc index eb5ffa6..1aaa529 100755 --- a/client/goodfet.cc +++ b/client/goodfet.cc @@ -100,6 +100,10 @@ if(sys.argv[1]=="erase"): # client.CCwriteflash(i,h[i>>1]); # if(i%0x100==0): # print "%04x" % i; + +if(sys.argv[1]=="flashpage"): + print "Writing a page of flash from 0xF000 in XDATA" + CCflashpage(0x0000); if(sys.argv[1]=="writedata"): f=sys.argv[2]; start=0; diff --git a/firmware/apps/chipcon/chipcon.c b/firmware/apps/chipcon/chipcon.c index 1a4846b..0ff9f03 100644 --- a/firmware/apps/chipcon/chipcon.c +++ b/firmware/apps/chipcon/chipcon.c @@ -219,15 +219,30 @@ void cchandle(unsigned char app, txdata(app,verb,1); break; case CC_SET_PC: - case CC_CLOCK_INIT: + cc_set_pc(cmddatalong[0]); + txdata(app,verb,0); + break; case CC_WRITE_FLASH_PAGE: + cc_write_flash_page(cmddatalong[0]); + txdata(app,verb,0); + break; case CC_MASS_ERASE_FLASH: + case CC_CLOCK_INIT: case CC_PROGRAM_FLASH: + debugstr("This Chipcon command is not yet implemented."); txdata(app,NOK,0);//TODO implement me. break; } } +//! Set the Chipcon's Program Counter +void cc_set_pc(u32 adr){ + cmddata[0]=0x02; //GetPC + cmddata[1]=(adr>>8)&0xff; //HIBYTE + cmddata[2]=adr&0xff; //LOBYTE + return; +} + //! Erase all of a Chipcon's memory. void cc_chip_erase(){ cmddata[0]=CCCMD_CHIP_ERASE; //0x14 @@ -271,6 +286,82 @@ unsigned short cc_get_chip_id(){ return toret; } +//! Populates flash buffer in xdata. +void cc_write_flash_buffer(u8 *data, u16 len){ + cc_write_xdata(0xf000, data, len); +} +//! Populates flash buffer in xdata. +void cc_write_xdata(u16 adr, u8 *data, u16 len){ + u16 i; + for(i=0; i> 8) / FLASH_WORD_SIZE) & 0x7E, + + 0x75, 0xAC, 0x00, // MOV FADDRL, #00; + /* Erase page. * + 0x75, 0xAE, 0x01, // MOV FLC, #01H; // ERASE + // ; Wait for flash erase to complete + 0xE5, 0xAE, // eraseWaitLoop: MOV A, FLC; + 0x20, 0xE7, 0xFB, // JB ACC_BUSY, eraseWaitLoop; + */ + // ; Initialize the data pointer + 0x90, 0xF0, 0x00, // MOV DPTR, #0F000H; + // ; Outer loops + 0x7F, HIBYTE_WORDS_PER_FLASH_PAGE, // MOV R7, #imm; + 0x7E, LOBYTE_WORDS_PER_FLASH_PAGE, // MOV R6, #imm; + 0x75, 0xAE, 0x02, // MOV FLC, #02H; // WRITE + // ; Inner loops + 0x7D, FLASH_WORD_SIZE, // writeLoop: MOV R5, #imm; + 0xE0, // writeWordLoop: MOVX A, @DPTR; + 0xA3, // INC DPTR; + 0xF5, 0xAF, // MOV FWDATA, A; + 0xDD, 0xFA, // DJNZ R5, writeWordLoop; + // ; Wait for completion + 0xE5, 0xAE, // writeWaitLoop: MOV A, FLC; + 0x20, 0xE6, 0xFB, // JB ACC_SWBSY, writeWaitLoop; + 0xDE, 0xF1, // DJNZ R6, writeLoop; + 0xDF, 0xEF, // DJNZ R7, writeLoop; + // ; Done, fake a breakpoint + 0xA5 // DB 0xA5; +}; + +//! Copies flash buffer to flash. +void cc_write_flash_page(u32 adr){ + //Assumes that page has already been written to XDATA 0xF000 + + //Routine comes next + //WRITE_XDATA_MEMORY(IN: 0xF000 + FLASH_PAGE_SIZE, sizeof(routine), routine); + cc_write_xdata(0xF000+FLASHPAGE_SIZE, + (u8*) flash_routine, sizeof(flash_routine)); + //Patch routine's third byte with + //((address >> 8) / FLASH_WORD_SIZE) & 0x7E + cc_pokedatabyte(0xF000+FLASHPAGE_SIZE+2, + ((adr>>8)/FLASH_WORD_SIZE)&0x7E); + cc_debug(3, //MOV MEMCTR, (bank * 16) + 1; + 0x75, 0xc7, 0x51); + cc_set_pc(0xf000+FLASHPAGE_SIZE);//execute code fragment + cc_resume(); + while(!(cc_read_status()&CC_STATUS_CPUHALTED)){ + P1OUT^=1;//blink LED + } + + P1OUT&=~1;//clear LED +} //! Read the PC unsigned short cc_get_pc(){ diff --git a/firmware/include/chipcon.h b/firmware/include/chipcon.h index dd96f81..73906ab 100644 --- a/firmware/include/chipcon.h +++ b/firmware/include/chipcon.h @@ -3,6 +3,7 @@ \brief Chipcon application functions. */ +#include "command.h" //Chipcon command definitions. #define CCCMD_CHIP_ERASE 0x14 @@ -45,6 +46,15 @@ unsigned char cc_debug(unsigned char len, unsigned char b, unsigned char c); +//! Populates flash buffer in xdata. +void cc_write_flash_buffer(u8 *data, u16 len); +//! Populates flash buffer in xdata. +void cc_write_xdata(u16 adr, u8 *data, u16 len); +//! Copies flash buffer to flash. +void cc_write_flash_page(u32 adr); +//! Set the Chipcon's Program Counter +void cc_set_pc(u32 adr); + //! Halt the CPU. void cc_halt(); //! Resume the CPU. @@ -52,6 +62,14 @@ void cc_resume(); //! Step an instruction void cc_step_instr(); +#define CC_STATUS_ERASED 0x80 +#define CC_STATUS_PCONIDLE 0x40 +#define CC_STATUS_CPUHALTED 0x20 +#define CC_STATUS_PM0 0x10 +#define CC_STATUS_HALTSTATUS 0x08 +#define CC_STATUS_LOCKED 0x04 +#define CC_STATUS_OSCSTABLE 0x02 +#define CC_STATUS_OVERFLOW 0x01 //CHIPCON commands #define CC_CHIP_ERASE 0x80 -- 2.20.1