fix read for verify_image
[openocd.git] / src / target / dsp5680xx.c
index 12b323ed03b8b4112cda1e4613bd1b4d7d88a9db..da9ba46a7556ebad426bfc93c2e321d47cf16166 100644 (file)
@@ -28,7 +28,7 @@
 #include "target_type.h"
 #include "dsp5680xx.h"
 
-#define err_check(retval,err_msg) if(retval != ERROR_OK){LOG_ERROR("%s: %s.",__FUNCTION__,err_msg);return retval;}
+#define err_check(retval,err_msg) if(retval != ERROR_OK){LOG_ERROR("%s: %d %s.",__FUNCTION__,__LINE__,err_msg);return retval;}
 #define err_check_propagate(retval) if(retval!=ERROR_OK){return retval;}
 
 // Forward declarations, could try to optimize this.
@@ -135,7 +135,7 @@ static int dsp5680xx_read_core_reg(struct target * target, uint8_t reg_addr, uin
 }
 
 static int dsp5680xx_target_create(struct target *target, Jim_Interp * interp){
-  struct dsp5680xx_common *dsp5680xx = calloc(1, sizeof(struct dsp5680xx_common)); 
+  struct dsp5680xx_common *dsp5680xx = calloc(1, sizeof(struct dsp5680xx_common));
   target->arch_info = dsp5680xx;
   return ERROR_OK;
 }
@@ -153,21 +153,16 @@ static int dsp5680xx_arch_state(struct target *target){
   return ERROR_OK;
 }
 
-int dsp5680xx_target_status(struct target * target, uint8_t * jtag_st, uint16_t * eonce_st){  
+int dsp5680xx_target_status(struct target * target, uint8_t * jtag_st, uint16_t * eonce_st){
   return target->state;
 }
 
 static int dsp5680xx_assert_reset(struct target *target){
-  //TODO verify the sleeps are necessary
-  jtag_add_reset(1,0);
   target->state = TARGET_RESET;
-  jtag_add_sleep(500);
-  sleep(1);
   return ERROR_OK;
 }
 
 static int dsp5680xx_deassert_reset(struct target *target){
-  jtag_add_reset(0,0);
   target->state = TARGET_RUNNING;
   return ERROR_OK;
 }
@@ -179,7 +174,6 @@ static int dsp5680xx_poll(struct target *target){
   uint16_t read_tmp;
   retval = dsp5680xx_jtag_status(target,&jtag_status);
   err_check_propagate(retval);
-  LOG_DEBUG("JTAG 0x%02X",jtag_status);//TODO remove!!
   if (jtag_status == JTAG_STATUS_DEBUG)
     if (target->state != TARGET_HALTED){
       retval = eonce_enter_debug_mode(target,&read_tmp);
@@ -189,7 +183,7 @@ static int dsp5680xx_poll(struct target *target){
                LOG_WARNING("%s: Failed to put EOnCE in debug mode. Is flash locked?...",__FUNCTION__);
                return ERROR_TARGET_FAILURE;
       }else{
-               target->state = TARGET_HALTED;   
+               target->state = TARGET_HALTED;
                return ERROR_OK;
       }
     }
@@ -218,7 +212,7 @@ static int dsp5680xx_poll(struct target *target){
     }
     target->state = TARGET_RUNNING;
     return ERROR_OK;
-  }      
+  }
   if(jtag_status == JTAG_STATUS_DEAD){
     LOG_ERROR("%s: Cannot communicate with JTAG. Check connection...",__FUNCTION__);
     target->state = TARGET_UNKNOWN;
@@ -250,17 +244,6 @@ static int eonce_read_status_reg(struct target * target, uint16_t * data){
   return retval;
 }
 
-static int dsp5680xx_obase_addr(struct target * target, uint32_t * addr){
-  // Finds out the default value of the OBASE register address.
-  int retval;
-  uint32_t data_to_shift_into_dr;// just to make jtag happy
-  retval = eonce_instruction_exec(target,DSP5680XX_ONCE_OBASE,1,0,0,NULL);
-  err_check_propagate(retval);
-  retval = dsp5680xx_drscan(target,(uint8_t *)& data_to_shift_into_dr,(uint8_t *) addr, 8);
-  err_check_propagate(retval);
-  return retval;
-}
-
 static int dsp5680xx_halt(struct target *target){
   int retval;
   uint8_t jtag_status;
@@ -287,7 +270,7 @@ static int dsp5680xx_resume(struct target *target, int current, uint32_t address
   int retval;
   uint8_t jtag_status;
   uint16_t eonce_status;
-  
+
   // Verify that EOnCE is enabled (enable it if necessary)
   uint16_t data_read_from_dr = 0;
   retval = eonce_read_status_reg(target,&data_read_from_dr);
@@ -300,7 +283,7 @@ static int dsp5680xx_resume(struct target *target, int current, uint32_t address
     retval = eonce_move_value_to_pc(target,address);
     err_check_propagate(retval);
   }
-  
+
   int retry = 20;
   while(retry-- > 1){
     retval = eonce_exit_debug_mode(target,(uint8_t *)&eonce_status );
@@ -309,7 +292,7 @@ static int dsp5680xx_resume(struct target *target, int current, uint32_t address
        err_check_propagate(retval);
     if((jtag_status & 0xff) == JTAG_STATUS_NORMAL){
       break;
-    }  
+    }
   }
   if(retry == 0){
     retval = ERROR_TARGET_FAILURE;
@@ -355,7 +338,7 @@ static int eonce_enter_debug_mode(struct target * target, uint16_t * eonce_statu
   // Debug request #1
   retval = dsp5680xx_irscan(target,& instr,& ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN);
   err_check_propagate(retval);
+
   // Enable EOnCE module
   instr = JTAG_INSTR_ENABLE_ONCE;
   //Two rounds of jtag 0x6  (enable eonce) to enable EOnCE.
@@ -620,25 +603,15 @@ static int eonce_move_value_to_pc(struct target * target, uint32_t value)
 
 static int eonce_load_TX_RX_to_r0(struct target * target)
 {
-  //TODO add error control
-  uint32_t obase_addr;
-  int retval = dsp5680xx_obase_addr(target,& obase_addr);
-  eonce_move_long_to_r0(target,((MC568013_EONCE_TX_RX_ADDR)+(obase_addr<<16)));
+  int retval;
+  retval = eonce_move_long_to_r0(target,((MC568013_EONCE_TX_RX_ADDR)+(MC568013_EONCE_OBASE_ADDR<<16)));
   return retval;
 }
 
 static int eonce_load_TX_RX_high_to_r0(struct target * target)
 {
-  //TODO add error control
-  uint32_t obase_addr;
-  int retval = dsp5680xx_obase_addr(target,& obase_addr);
-  err_check_propagate(retval);
-  if(!(obase_addr && 0xff)){
-       LOG_USER("%s: OBASE address read as 0x%04X instead of 0xFF.",__FUNCTION__,obase_addr);
-       return ERROR_FAIL;
-  }
-  eonce_move_long_to_r0(target,((MC568013_EONCE_TX1_RX1_HIGH_ADDR)+(obase_addr<<16)));
-  err_check_propagate(retval);
+  int retval = 0;
+  retval = eonce_move_long_to_r0(target,((MC568013_EONCE_TX1_RX1_HIGH_ADDR)+(MC568013_EONCE_OBASE_ADDR<<16)));
   return retval;
 }
 
@@ -708,7 +681,7 @@ static int dsp5680xx_read_32_single(struct target * target, uint32_t address, ui
        err_check_propagate(retval);
     retval = eonce_move_at_r0_to_y1(target);
        err_check_propagate(retval);
-  } 
+  }
   // Get lower part of data to TX/RX
   retval = eonce_load_TX_RX_to_r0(target);
   err_check_propagate(retval);
@@ -723,7 +696,7 @@ static int dsp5680xx_read_32_single(struct target * target, uint32_t address, ui
   uint16_t tmp;
   retval = eonce_rx_upper_data(target,&tmp);
   err_check_propagate(retval);
-  *data_read = (((*data_read)<<16) | tmp);
+  *data_read = ((tmp<<16) | (*data_read));//This enables opencd crc to succeed, even though it's very slow.
   return retval;
 }
 
@@ -737,11 +710,18 @@ static int dsp5680xx_read(struct target * target, uint32_t address, unsigned siz
   int retval = ERROR_OK;
   int pmem = 1;
   uint16_t tmp_wrd;
-  
+
   retval = dsp5680xx_convert_address(&address, &pmem);
   err_check_propagate(retval);
 
+  context.flush = 0;
+  int counter = FLUSH_COUNT_READ_WRITE;
+
   for (unsigned i=0; i<count; i++){
+    if(--counter==0){
+      context.flush = 1;
+      counter = FLUSH_COUNT_FLASH;
+    }
     switch (size){
     case 1:
       if(!(i%2)){
@@ -761,7 +741,13 @@ static int dsp5680xx_read(struct target * target, uint32_t address, unsigned siz
       break;
     }
        err_check_propagate(retval);
+    context.flush = 0;
   }
+  
+  context.flush = 1;
+  retval = dsp5680xx_execute_queue();
+  err_check_propagate(retval);
+  
   return retval;
 }
 
@@ -811,22 +797,19 @@ static int dsp5680xx_write_8(struct target * target, uint32_t address, uint32_t
   uint16_t * data_w = (uint16_t *)data;
   uint32_t iter;
 
-  int counter_reset = FLUSH_COUNT_WRITE;
-  int counter = counter_reset;
-
+  int counter = FLUSH_COUNT_READ_WRITE;
   for(iter = 0; iter<count/2; iter++){
-       if(--counter==0){
-         context.flush = 1;
-         counter = counter_reset;
-       }
-
+    if(--counter==0){
+      context.flush = 1;
+      counter = FLUSH_COUNT_READ_WRITE;
+    }
     retval = dsp5680xx_write_16_single(target,address+iter,data_w[iter], pmem);
     if(retval != ERROR_OK){
       LOG_ERROR("%s: Could not write to p:0x%04X",__FUNCTION__,address);
-         context.flush = 1;
+      context.flush = 1;
       return retval;
     }
-       context.flush = 0;
+    context.flush = 0;
   }
   context.flush = 1;
 
@@ -853,14 +836,12 @@ static int dsp5680xx_write_16(struct target * target, uint32_t address, uint32_t
        err_check(retval,"Target must be halted.");
   };
   uint32_t iter;
-
-  int counter_reset = FLUSH_COUNT_WRITE;
-  int counter = counter_reset;
+  int counter = FLUSH_COUNT_READ_WRITE;
 
   for(iter = 0; iter<count; iter++){
        if(--counter==0){
          context.flush = 1;
-         counter = counter_reset;
+      counter = FLUSH_COUNT_READ_WRITE;
        }
     retval = dsp5680xx_write_16_single(target,address+iter,data[iter], pmem);
     if(retval != ERROR_OK){
@@ -881,14 +862,12 @@ static int dsp5680xx_write_32(struct target * target, uint32_t address, uint32_t
        err_check(retval,"Target must be halted.");
   };
   uint32_t iter;
-
-  int counter_reset = FLUSH_COUNT_WRITE;
-  int counter = counter_reset;
+  int counter = FLUSH_COUNT_READ_WRITE;
 
   for(iter = 0; iter<count; iter++){
        if(--counter==0){
          context.flush = 1;
-         counter = counter_reset;
+      counter = FLUSH_COUNT_READ_WRITE;
        }
     retval = dsp5680xx_write_32_single(target,address+(iter<<1),data[iter], pmem);
     if(retval != ERROR_OK){
@@ -904,7 +883,7 @@ static int dsp5680xx_write_32(struct target * target, uint32_t address, uint32_t
 
 //TODO doxy
 static int dsp5680xx_write(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t * buffer){
-  //TODO Cannot write 32bit to odd address, will write 0x1234567 to as 0x5678 0x0012
+  //TODO Cannot write 32bit to odd address, will write 0x1234567 as 0x5678 0x0012
   if(target->state != TARGET_HALTED){
     LOG_USER("Target must be halted.");
     return ERROR_OK;
@@ -913,7 +892,7 @@ static int dsp5680xx_write(struct target *target, uint32_t address, uint32_t siz
   int p_mem = 1;
   retval = dsp5680xx_convert_address(&address, &p_mem);
   err_check_propagate(retval);
-  
+
   switch (size){
   case 1:
     retval = dsp5680xx_write_8(target, address, count,(uint8_t *) buffer, p_mem);
@@ -939,12 +918,12 @@ static int dsp5680xx_bulk_write_memory(struct target * target,uint32_t address,
 
 // Writes to pram at address
 // r3 holds the destination address-> p:(r3)
-// r2 hold 0xf151 to flash a led (probably cannot see it due to high freq.) 
+// r2 hold 0xf151 to flash a led (probably cannot see it due to high freq.)
 // r0 holds TX/RX address.
 //0x00000073  0x8A44FFFE017B         brclr       #1,X:(R0-2),*-2
-//0x00000076  0xE700                 nop         
+//0x00000076  0xE700                 nop
 //0x00000077  0xF514                 move.w      X:(R0),Y0
-//0x00000078  0xE700                 nop         
+//0x00000078  0xE700                 nop
 //0x00000079  0x8563                 move.w      Y0,P:(R3)+
 //0x0000007A  0x84420003             bfchg       #3,X:(R2)
 //0x0000007C  0xA976                 bra         *-9
@@ -963,27 +942,32 @@ static int dsp5680xx_read_buffer(struct target * target, uint32_t address, uint3
     LOG_USER("Target must be halted.");
     return ERROR_OK;
   }
-  // byte addressing!
-  int retval = ERROR_OK;
-  int pmem = 1;
-  uint16_t tmp_wrd= 0;
-
-  retval = dsp5680xx_convert_address(&address, &pmem);
-  err_check_propagate(retval);
-
-  for (unsigned i=0; i<size; i++)
-    if(!(i%2)){
-      retval = dsp5680xx_read_16_single(target, address + i/2, &tmp_wrd, pmem);
-         err_check_propagate(retval);
-      //TODO find a better solution. endiannes differs from normal read, otherwise the openocd crc would do weird stuff.
-      buffer[i+1] = (uint8_t) (tmp_wrd>>8);
-      buffer[i] = (uint8_t) (tmp_wrd&0xff);
-   }
-  return retval;
+  // read_buffer is called when the verify_image command is executed.
+  // The "/2" solves the byte/word addressing issue. 
+  return dsp5680xx_read(target,address,2,size/2,buffer);
 }
 
 static int dsp5680xx_checksum_memory(struct target * target, uint32_t address, uint32_t size, uint32_t * checksum){
-  return ERROR_FAIL; //this makes openocd do the crc
+  return ERROR_FAIL;// This will make OpenOCD do the read out the data and verify it.
+}
+
+// Data signature algorithm used by the core FM (flash module)
+static int perl_crc(uint16_t * buff16,uint32_t  word_count){
+  uint16_t checksum = 0xffff;
+  uint16_t data,fbmisr;
+  uint32_t i;
+  for(i=0;i<word_count;i++){
+    data = buff16[i];
+    fbmisr = (checksum & 2)>>1 ^ (checksum & 4)>>2 ^ (checksum & 16)>>4 ^ (checksum & 0x8000)>>15;
+    checksum = (data ^ ((checksum << 1) | fbmisr));
+  }
+  i--;
+  for(;!(i&0x80000000);i--){
+    data = buff16[i];
+    fbmisr = (checksum & 2)>>1 ^ (checksum & 4)>>2 ^ (checksum & 16)>>4 ^ (checksum & 0x8000)>>15;
+    checksum = (data ^ ((checksum << 1) | fbmisr));
+  }
+  return checksum;
 }
 
 int dsp5680xx_f_SIM_reset(struct target * target){
@@ -1009,33 +993,23 @@ static int dsp5680xx_soft_reset_halt(struct target *target){
   return retval;
 }
 
-int dsp5680xx_f_protect_check(struct target * target, uint8_t * protected) {
-  uint16_t i,j;
+int dsp5680xx_f_protect_check(struct target * target, uint16_t * protected) {
+  uint16_t aux;
   int retval;
   if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
     retval = dsp5680xx_halt(target);
        err_check_propagate(retval);
   }
-  retval = eonce_load_TX_RX_high_to_r0(target);
-  err_check_propagate(retval);
-  retval = eonce_move_value_to_y0(target,0x1234);
-  err_check_propagate(retval);
-  retval = eonce_move_y0_at_r0(target);
-  err_check_propagate(retval);
-  retval = eonce_rx_upper_data(target,&i);
-  err_check_propagate(retval);
-  retval = eonce_move_value_to_y0(target,0x4321);
-  err_check_propagate(retval);
-  retval = eonce_move_y0_at_r0(target);
-  err_check_propagate(retval);
-  retval = eonce_rx_upper_data(target,&j);
+  if(protected == NULL){
+    err_check(ERROR_FAIL,"NULL pointer not valid.");
+  }
+  retval = dsp5680xx_read_16_single(target,HFM_BASE_ADDR|HFM_PROT,&aux,0);
   err_check_propagate(retval);
-  if(protected!=NULL)
-    *protected = (uint8_t) ((i!=0x1234)||(j!=0x4321));
+  *protected = aux;
   return retval;
 }
 
-static int dsp5680xx_f_execute_command(struct target * target, uint16_t command, uint32_t address, uint16_t * hfm_ustat, int pmem){
+static int dsp5680xx_f_execute_command(struct target * target, uint16_t command, uint32_t address, uint32_t data, uint16_t * hfm_ustat, int pmem){
   int retval;
   retval = eonce_load_TX_RX_high_to_r0(target);
   err_check_propagate(retval);
@@ -1067,6 +1041,8 @@ static int dsp5680xx_f_execute_command(struct target * target, uint16_t command,
   err_check_propagate(retval);
   retval = eonce_move_value_at_r2_disp(target,0x00,HFM_PROTB);         // write to HMF_PROTB, clear protection
   err_check_propagate(retval);
+  retval = eonce_move_value_to_y0(target,data);
+  err_check_propagate(retval);
   retval = eonce_move_long_to_r3(target,address);                      // write to the flash block
   err_check_propagate(retval);
   if (pmem){
@@ -1088,7 +1064,7 @@ static int dsp5680xx_f_execute_command(struct target * target, uint16_t command,
        err_check_propagate(retval);
        retval = eonce_rx_upper_data(target,&i);
        err_check_propagate(retval);
-    if((watchdog--)==1){      
+    if((watchdog--)==1){
          retval = ERROR_TARGET_FAILURE;
       err_check(retval,"FM execution did not finish.");
     }
@@ -1135,32 +1111,32 @@ static int eonce_set_hfmdiv(struct target * target){
   return ERROR_OK;
 }
 
-int dsp5680xx_f_erase_check(struct target * target, uint8_t * erased){
+static int dsp5680xx_f_signature(struct target * target, uint32_t address, uint32_t words, uint16_t * signature){
   int retval;
   uint16_t hfm_ustat;
   if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
-    retval = dsp5680xx_halt(target);
+    retval = eonce_enter_debug_mode(target,NULL);
     err_check_propagate(retval);
   }
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-  // Check security
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-  uint8_t protected;
-  retval = dsp5680xx_f_protect_check(target,&protected);
+  retval = dsp5680xx_f_execute_command(target,HFM_CALCULATE_DATA_SIGNATURE,address,words,&hfm_ustat,1);
   err_check_propagate(retval);
-  if(protected){
-       retval = ERROR_TARGET_FAILURE;
-       err_check(retval,"Failed to erase, flash is still protected.");
+  if (hfm_ustat&HFM_USTAT_MASK_PVIOL_ACCER){
+    retval = ERROR_TARGET_FAILURE;
+    err_check(retval,"HFM exec error:pviol and/or accer bits set.");
   }
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-  // Set hfmdiv
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-  retval = eonce_set_hfmdiv(target);
-  err_check_propagate(retval);
+  retval = dsp5680xx_read_16_single(target, HFM_BASE_ADDR|HFM_DATA, signature, 0);
+  return retval;
+}
 
+int dsp5680xx_f_erase_check(struct target * target, uint8_t * erased,uint32_t sector){
+  int retval;
+  uint16_t hfm_ustat;
+  if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
+    retval = dsp5680xx_halt(target);
+    err_check_propagate(retval);
+  }
   // Check if chip is already erased.
-  // Since only mass erase is currently implemented, only the first sector is checked (assuming no code will leave it unused)
-  retval = dsp5680xx_f_execute_command(target,HFM_ERASE_VERIFY,HFM_FLASH_BASE_ADDR+0*HFM_SECTOR_SIZE,&hfm_ustat,1); // blank check
+  retval = dsp5680xx_f_execute_command(target,HFM_ERASE_VERIFY,HFM_FLASH_BASE_ADDR+sector*HFM_SECTOR_SIZE/2,0,&hfm_ustat,1); // blank check
   err_check_propagate(retval);
   if (hfm_ustat&HFM_USTAT_MASK_PVIOL_ACCER){
        retval = ERROR_TARGET_FAILURE;
@@ -1170,67 +1146,51 @@ int dsp5680xx_f_erase_check(struct target * target, uint8_t * erased){
     *erased = (uint8_t)(hfm_ustat&HFM_USTAT_MASK_BLANK);
   return retval;
 }
+  
+static int erase_sector(struct target * target, int sector, uint16_t * hfm_ustat){
+  int retval;
+  retval = dsp5680xx_f_execute_command(target,HFM_PAGE_ERASE,HFM_FLASH_BASE_ADDR+sector*HFM_SECTOR_SIZE/2,0,hfm_ustat,1);
+  err_check_propagate(retval);
+  return retval;
+}
+static int mass_erase(struct target * target, uint16_t * hfm_ustat){
+  int retval;
+  retval = dsp5680xx_f_execute_command(target,HFM_MASS_ERASE,0,0,hfm_ustat,1);
+  return retval;
+}
 
 int dsp5680xx_f_erase(struct target * target, int first, int last){
-  //TODO implement erasing individual sectors.
   int retval;
-  if(first||last){
-       retval = ERROR_FAIL;
-       err_check(retval,"Sector erasing not implemented. Call with first=last=0.");
-  }
   if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
     retval = dsp5680xx_halt(target);
-       err_check_propagate(retval);
+    err_check_propagate(retval);
   }
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   // Reset SIM
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   retval = dsp5680xx_f_SIM_reset(target);
   err_check_propagate(retval);
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-  // Check security
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-  uint8_t protected;
-  retval = dsp5680xx_f_protect_check(target,&protected);
-  err_check_propagate(retval);
-  if(protected){
-       retval = ERROR_TARGET_FAILURE;
-       err_check(retval,"Cannot flash, security is still enabled.");
-  }
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   // Set hfmdiv
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   retval = eonce_set_hfmdiv(target);
   err_check_propagate(retval);
 
-  // Check if chip is already erased.
-  // Since only mass erase is currently implemented, only the first sector is checked (assuming no code will leave it unused)
-  uint8_t erased;
-  retval = dsp5680xx_f_erase_check(target,&erased);
-  err_check_propagate(retval);
-  if (erased)
-    LOG_USER("Flash blank - mass erase skipped.");
-  else{
-    // Execute mass erase command.
-       uint16_t hfm_ustat;
-       uint16_t hfm_cmd = HFM_MASS_ERASE;
-    retval = dsp5680xx_f_execute_command(target,hfm_cmd,HFM_FLASH_BASE_ADDR+0*HFM_SECTOR_SIZE,&hfm_ustat,1);
-       err_check_propagate(retval);
-    if (hfm_ustat&HFM_USTAT_MASK_PVIOL_ACCER){
-         retval = ERROR_TARGET_FAILURE;
-         err_check(retval,"pviol and/or accer bits set. HFM command execution error");
-    }
-    // Verify flash was successfully erased.
-    retval = dsp5680xx_f_erase_check(target,&erased);   
+  uint16_t hfm_ustat;
+  int do_mass_erase = ((!(first|last)) || ((first==0)&&(last == (HFM_SECTOR_COUNT-1))));
+  if(do_mass_erase){
+    //Mass erase
+    retval = mass_erase(target,&hfm_ustat);
+    err_check_propagate(retval);
+    last = HFM_SECTOR_COUNT-1;
+  }else{
+    for(int i = first;i<=last;i++){
+      retval = erase_sector(target,i,&hfm_ustat);
        err_check_propagate(retval);
-       if(retval == ERROR_OK){
-      if (erased)
-               LOG_USER("Flash mass erased and checked blank.");
-      else
-               LOG_WARNING("Flash mass erased, but still not blank!");
-    }
   }
-  return retval;
+  }
+  return ERROR_OK;
 }
 
 // Algorithm for programming normal p: flash
@@ -1256,10 +1216,10 @@ int dsp5680xx_f_erase(struct target * target, int first, int last){
 //                      bfset       #0x10,X:(R2+0x13)               // clear accerr
 //                     bra         hfm_wait                        // loop
 //0x00000073  0x8A460013407D         brclr       #0x40,X:(R2+0x13),*+0
-//0x00000076  0xE700                 nop         
-//0x00000077  0xE700                 nop         
+//0x00000076  0xE700                 nop
+//0x00000077  0xE700                 nop
 //0x00000078  0x8A44FFFE017B         brclr       #1,X:(R0-2),*-2
-//0x0000007B  0xE700                 nop         
+//0x0000007B  0xE700                 nop
 //0x0000007C  0xF514                 move.w      X:(R0),Y0
 //0x0000007D  0x8563                 move.w      Y0,P:(R3)+
 //0x0000007E  0x864600200014         move.w      #0x20,X:(R2+0x14)
@@ -1280,41 +1240,31 @@ int dsp5680xx_f_wr(struct target * target, uint8_t *buffer, uint32_t address, ui
     retval = dsp5680xx_halt(target);
        err_check_propagate(retval);
   }
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-  // Check if flash is erased
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-  uint8_t erased;
-  retval = dsp5680xx_f_erase_check(target,&erased);
-  err_check_propagate(retval);
-  if(!erased){
-       retval = ERROR_FAIL;
-       err_check(retval,"Flash must be erased before flashing.");
-  }    
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   // Download the pgm that flashes.
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   uint32_t my_favourite_ram_address = 0x8700; // This seems to be a safe address. This one is the one used by codewarrior in 56801x_flash.cfg
   retval = dsp5680xx_write(target, my_favourite_ram_address, 1, pgm_write_pflash_length*2,(uint8_t *) pgm_write_pflash);
   err_check_propagate(retval);
   retval = dsp5680xx_execute_queue();
   err_check_propagate(retval);
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   // Set hfmdiv
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   retval = eonce_set_hfmdiv(target);
   err_check_propagate(retval);
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   // Setup registers needed by pgm_write_pflash
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   retval = eonce_move_long_to_r3(target,address);  // Destination address to r3
   err_check_propagate(retval);
   eonce_load_TX_RX_high_to_r0(target);  // TX/RX reg address to r0
   err_check_propagate(retval);
   retval = eonce_move_long_to_r2(target,HFM_BASE_ADDR);// FM base address to r2
   err_check_propagate(retval);
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   // Run flashing program.
-  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   retval = eonce_move_value_at_r2_disp(target,0x00,HFM_CNFG); // write to HFM_CNFG (lock=0, select bank)
   err_check_propagate(retval);
   retval = eonce_move_value_at_r2_disp(target,0x04,HFM_USTAT);// write to HMF_USTAT, clear PVIOL, ACCERR & BLANK bits
@@ -1339,14 +1289,14 @@ int dsp5680xx_f_wr(struct target * target, uint8_t *buffer, uint32_t address, ui
   retval = dsp5680xx_resume(target,0,my_favourite_ram_address,0,0);
   err_check_propagate(retval);
 
-  int counter_reset = FLUSH_COUNT_FLASH;
-  int counter = counter_reset;
+  int counter = FLUSH_COUNT_FLASH;
   context.flush = 0;
-  for(uint32_t i=1; (i<count/2)&&(i<HFM_SIZE_REAL); i++){ 
-       if(--counter==0){
-         context.flush = 1;
-         counter = counter_reset;
-       }
+  uint32_t i;
+  for(i=1; (i<count/2)&&(i<HFM_SIZE_WORDS); i++){
+    if(--counter==0){
+      context.flush = 1;
+      counter = FLUSH_COUNT_FLASH;
+    }
     retval = eonce_tx_upper_data(target,buff16[i],&drscan_data);
        if(retval!=ERROR_OK){
          context.flush = 1;
@@ -1355,9 +1305,23 @@ int dsp5680xx_f_wr(struct target * target, uint8_t *buffer, uint32_t address, ui
        context.flush = 0;
   }
   context.flush = 1;
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+  // Verify flash
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+  uint16_t signature;
+  uint16_t pc_crc;
+  retval =  dsp5680xx_f_signature(target,address,i,&signature);
+  err_check_propagate(retval);
+  pc_crc = perl_crc(buff16,i);
+  if(pc_crc != signature){
+    retval = ERROR_FAIL;
+    err_check(retval,"Flashed data failed CRC check, flash again!");
+  }
   return retval;
 }
 
+
+
 int dsp5680xx_f_unlock(struct target * target){
   int retval;
   if(target->tap->enabled){
@@ -1365,8 +1329,8 @@ int dsp5680xx_f_unlock(struct target * target){
     LOG_ERROR("Master tap must be enabled to unlock flash.");
     return ERROR_TARGET_FAILURE;
   }
-  uint32_t data_to_shift_in = MASTER_TAP_CMD_FLASH_ERASE;  
-  uint32_t data_shifted_out;  
+  uint32_t data_to_shift_in = MASTER_TAP_CMD_FLASH_ERASE;
+  uint32_t data_shifted_out;
   retval = dsp5680xx_irscan(target,&data_to_shift_in,&data_shifted_out,8);
   err_check_propagate(retval);
   data_to_shift_in = HFM_CLK_DEFAULT;
@@ -1403,7 +1367,7 @@ struct target_type dsp5680xx_target = {
   .write_buffer = dsp5680xx_write_buffer,
   .read_buffer = dsp5680xx_read_buffer,
 
-  .assert_reset = dsp5680xx_assert_reset,  
+  .assert_reset = dsp5680xx_assert_reset,
   .deassert_reset = dsp5680xx_deassert_reset,
   .soft_reset_halt = dsp5680xx_soft_reset_halt,
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)