Working toward support for writing flash on Chipcon.
authortravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Sat, 17 Oct 2009 08:57:34 +0000 (08:57 +0000)
committertravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Sat, 17 Oct 2009 08:57:34 +0000 (08:57 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@201 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETCC.py
client/goodfet.cc
firmware/apps/chipcon/chipcon.c
firmware/include/chipcon.h

index d171f86..96e9c60 100644 (file)
@@ -114,9 +114,9 @@ class GoodFETCC(GoodFET):
         return ord(self.data[0])
     CCstatusbits={0x80 : "erased",
                   0x40 : "pcon_idle",
         return ord(self.data[0])
     CCstatusbits={0x80 : "erased",
                   0x40 : "pcon_idle",
-                  0x20 : "halted",
+                  0x20 : "cpu_halted",
                   0x10 : "pm0",
                   0x10 : "pm0",
-                  0x08 : "halted",
+                  0x08 : "halt_status",
                   0x04 : "locked",
                   0x02 : "oscstable",
                   0x01 : "overflow"};
                   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 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);
 
 
index eb5ffa6..1aaa529 100755 (executable)
@@ -100,6 +100,10 @@ if(sys.argv[1]=="erase"):
 #             client.CCwriteflash(i,h[i>>1]);
 #             if(i%0x100==0):
 #                 print "%04x" % i;
 #             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;
 if(sys.argv[1]=="writedata"):
     f=sys.argv[2];
     start=0;
index 1a4846b..0ff9f03 100644 (file)
@@ -219,15 +219,30 @@ void cchandle(unsigned char app,
     txdata(app,verb,1);
     break;
   case CC_SET_PC:
     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:
   case CC_WRITE_FLASH_PAGE:
+    cc_write_flash_page(cmddatalong[0]);
+    txdata(app,verb,0);
+    break;
   case CC_MASS_ERASE_FLASH:
   case CC_MASS_ERASE_FLASH:
+  case CC_CLOCK_INIT:
   case CC_PROGRAM_FLASH:
   case CC_PROGRAM_FLASH:
+    debugstr("This Chipcon command is not yet implemented.");
     txdata(app,NOK,0);//TODO implement me.
     break;
   }
 }
 
     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
 //! 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;
 }
 
   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<len; i++){
+    cc_pokedatabyte(adr+i,
+                   data[i]);
+  }
+}
+
+
+//256 words/page
+#define HIBYTE_WORDS_PER_FLASH_PAGE 0x00
+#define LOBYTE_WORDS_PER_FLASH_PAGE 0x80
+#define FLASHPAGE_SIZE 0x100
+//2 bytes/word
+#define FLASH_WORD_SIZE 0x2
+
+const u8 flash_routine[] = {
+  //MOV FADDRH, #imm; 
+  0x75, 0xAD,
+  0x00,//#imm=((address >> 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(){
 
 //! Read the PC
 unsigned short cc_get_pc(){
index dd96f81..73906ab 100644 (file)
@@ -3,6 +3,7 @@
   \brief Chipcon application functions.
 */
 
   \brief Chipcon application functions.
 */
 
+#include "command.h"
 
 //Chipcon command definitions.
 #define CCCMD_CHIP_ERASE 0x14
 
 //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);
 
                       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.
 //! Halt the CPU.
 void cc_halt();
 //! Resume the CPU.
@@ -52,6 +62,14 @@ void cc_resume();
 //! Step an instruction
 void cc_step_instr();
 
 //! 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
 
 //CHIPCON commands
 #define CC_CHIP_ERASE 0x80