kopia lustrzana https://github.com/stlink-org/stlink
				
				
				
			Merge 0164043f92 into adaf602a56
				
					
				
			
						commit
						d078a70dfd
					
				
							
								
								
									
										78
									
								
								flash/main.c
								
								
								
								
							
							
						
						
									
										78
									
								
								flash/main.c
								
								
								
								
							| 
						 | 
					@ -9,10 +9,10 @@
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include "stlink-common.h"
 | 
					#include "stlink-common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum st_cmds {DO_WRITE = 0, DO_READ = 1, DO_ERASE = 2};
 | 
				
			||||||
struct opts
 | 
					struct opts
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  unsigned int do_read;
 | 
					  enum st_cmds cmd;
 | 
				
			||||||
  const char* devname;
 | 
					  const char* devname;
 | 
				
			||||||
  const char* filename;
 | 
					  const char* filename;
 | 
				
			||||||
  stm32_addr_t addr;
 | 
					  stm32_addr_t addr;
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,9 @@ struct opts
 | 
				
			||||||
static void usage(void)
 | 
					static void usage(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    puts("stlinkv1 command line: ./flash {read|write} /dev/sgX path addr <size>");
 | 
					    puts("stlinkv1 command line: ./flash {read|write} /dev/sgX path addr <size>");
 | 
				
			||||||
 | 
					    puts("stlinkv1 command line: ./flash /dev/sgX erase");
 | 
				
			||||||
    puts("stlinkv2 command line: ./flash {read|write} path addr <size>");
 | 
					    puts("stlinkv2 command line: ./flash {read|write} path addr <size>");
 | 
				
			||||||
 | 
					    puts("stlinkv2 command line: ./flash erase");
 | 
				
			||||||
    puts("                       use hex format for addr and <size>");
 | 
					    puts("                       use hex format for addr and <size>");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,38 +35,52 @@ static int get_opts(struct opts* o, int ac, char** av)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned int i = 0;
 | 
					  unsigned int i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ac < 3) return -1;
 | 
					  if (ac < 1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* stlinkv2 */
 | 
					  /* stlinkv2 */
 | 
				
			||||||
  o->devname = NULL;
 | 
					  o->devname = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (strcmp(av[0], "read") == 0)
 | 
					  if (strcmp(av[0], "erase") == 0)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    o->do_read = 1;
 | 
					    o->cmd = DO_ERASE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* stlinkv1 mode */
 | 
					    /* stlinkv1 mode */
 | 
				
			||||||
    if (ac == 5)
 | 
					    if (ac == 2)
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      o->devname = av[1];
 | 
					 | 
				
			||||||
      i = 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (ac > 3)
 | 
					 | 
				
			||||||
	o->size = strtoul(av[i + 3], NULL, 16);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  else if (strcmp(av[0], "write") == 0)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    o->do_read = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* stlinkv1 mode */
 | 
					 | 
				
			||||||
    if (ac == 4)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      o->devname = av[1];
 | 
					      o->devname = av[1];
 | 
				
			||||||
      i = 1;
 | 
					      i = 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else {
 | 
				
			||||||
  {
 | 
					      if (ac < 3) return -1;
 | 
				
			||||||
    return -1;
 | 
					      if (strcmp(av[0], "read") == 0)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
						  o->cmd = DO_READ;
 | 
				
			||||||
 | 
						  
 | 
				
			||||||
 | 
						  /* stlinkv1 mode */
 | 
				
			||||||
 | 
						  if (ac == 5)
 | 
				
			||||||
 | 
						  {
 | 
				
			||||||
 | 
						      o->devname = av[1];
 | 
				
			||||||
 | 
						      i = 1;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						  if (ac > 3)
 | 
				
			||||||
 | 
						      o->size = strtoul(av[i + 3], NULL, 16);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else if (strcmp(av[0], "write") == 0)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
						  o->cmd = DO_WRITE;
 | 
				
			||||||
 | 
						  
 | 
				
			||||||
 | 
						  /* stlinkv1 mode */
 | 
				
			||||||
 | 
						  if (ac == 4)
 | 
				
			||||||
 | 
						  {
 | 
				
			||||||
 | 
						      o->devname = av[1];
 | 
				
			||||||
 | 
						      i = 1;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
						  return -1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  o->filename = av[i + 1];
 | 
					  o->filename = av[i + 1];
 | 
				
			||||||
| 
						 | 
					@ -107,9 +123,23 @@ int main(int ac, char** av)
 | 
				
			||||||
  if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE)
 | 
					  if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE)
 | 
				
			||||||
    stlink_enter_swd_mode(sl);
 | 
					    stlink_enter_swd_mode(sl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (o.do_read == 0) /* write */
 | 
					  if (o.cmd == DO_WRITE) /* write */
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    err = stlink_fwrite_flash(sl, o.filename, o.addr);
 | 
					    if ((o.addr >= sl->flash_base) &&
 | 
				
			||||||
 | 
						(o.addr < sl->flash_base + sl->flash_size))
 | 
				
			||||||
 | 
						err = stlink_fwrite_flash(sl, o.filename, o.addr);
 | 
				
			||||||
 | 
					    else if ((o.addr >= sl->sram_base) &&
 | 
				
			||||||
 | 
						     (o.addr < sl->sram_base + sl->sram_size))
 | 
				
			||||||
 | 
						err = stlink_fwrite_sram(sl, o.filename, o.addr);
 | 
				
			||||||
 | 
					    if (err == -1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      printf("stlink_fwrite_flash() == -1\n");
 | 
				
			||||||
 | 
					      goto on_error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (o.cmd == DO_ERASE) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					     err = stlink_erase_flash_mass(sl);
 | 
				
			||||||
    if (err == -1)
 | 
					    if (err == -1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      printf("stlink_fwrite_flash() == -1\n");
 | 
					      printf("stlink_fwrite_flash() == -1\n");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -265,15 +265,13 @@ static void init_data_watchpoints(stlink_t *sl) {
 | 
				
			||||||
	#endif
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// set trcena in debug command to turn on dwt unit
 | 
						// set trcena in debug command to turn on dwt unit
 | 
				
			||||||
	stlink_read_mem32(sl, 0xE000EDFC, 4);
 | 
						stlink_write_debug32(sl, 0xE000EDFC, 
 | 
				
			||||||
	sl->q_buf[3] |= 1;
 | 
								     stlink_read_debug32(sl, 0xE000EDFC) | (1<<24));
 | 
				
			||||||
	stlink_write_mem32(sl, 0xE000EDFC, 4);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// make sure all watchpoints are cleared
 | 
						// make sure all watchpoints are cleared
 | 
				
			||||||
	memset(sl->q_buf, 0, 4);
 | 
					 | 
				
			||||||
	for(int i = 0; i < DATA_WATCH_NUM; i++) {
 | 
						for(int i = 0; i < DATA_WATCH_NUM; i++) {
 | 
				
			||||||
		data_watches[i].fun = WATCHDISABLED;
 | 
							data_watches[i].fun = WATCHDISABLED;
 | 
				
			||||||
		stlink_write_mem32(sl, 0xe0001028 + i * 16, 4);
 | 
							stlink_write_debug32(sl, 0xe0001028 + i * 16, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -306,25 +304,16 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr
 | 
				
			||||||
				data_watches[i].mask = mask;
 | 
									data_watches[i].mask = mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// insert comparator address
 | 
									// insert comparator address
 | 
				
			||||||
				sl->q_buf[0] = (addr & 0xff);
 | 
									stlink_write_debug32(sl, 0xE0001020 + i * 16, addr);
 | 
				
			||||||
				sl->q_buf[1] = ((addr >> 8) & 0xff);
 | 
					 | 
				
			||||||
				sl->q_buf[2] = ((addr >> 16) & 0xff);
 | 
					 | 
				
			||||||
				sl->q_buf[3] = ((addr >> 24)  & 0xff);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				stlink_write_mem32(sl, 0xE0001020 + i * 16, 4);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// insert mask
 | 
									// insert mask
 | 
				
			||||||
				memset(sl->q_buf, 0, 4);
 | 
									stlink_write_debug32(sl, 0xE0001024 + i * 16, mask);
 | 
				
			||||||
				sl->q_buf[0] = mask;
 | 
					 | 
				
			||||||
				stlink_write_mem32(sl, 0xE0001024 + i * 16, 4);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// insert function
 | 
									// insert function
 | 
				
			||||||
				memset(sl->q_buf, 0, 4);
 | 
									stlink_write_debug32(sl, 0xE0001028 + i * 16, wf);
 | 
				
			||||||
				sl->q_buf[0] = wf;
 | 
					 | 
				
			||||||
				stlink_write_mem32(sl, 0xE0001028 + i * 16, 4);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// just to make sure the matched bit is clear !
 | 
									// just to make sure the matched bit is clear !
 | 
				
			||||||
				stlink_read_mem32(sl,  0xE0001028 + i * 16, 4);
 | 
									stlink_read_debug32(sl,  0xE0001028 + i * 16);
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -346,9 +335,8 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr)
 | 
				
			||||||
			printf("delete watchpoint %d addr %x\n", i, addr);
 | 
								printf("delete watchpoint %d addr %x\n", i, addr);
 | 
				
			||||||
			#endif
 | 
								#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			memset(sl->q_buf, 0, 4);
 | 
					 | 
				
			||||||
			data_watches[i].fun = WATCHDISABLED;
 | 
								data_watches[i].fun = WATCHDISABLED;
 | 
				
			||||||
			stlink_write_mem32(sl, 0xe0001028 + i * 16, 4);
 | 
								stlink_write_debug32(sl, 0xe0001028 + i * 16, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -374,15 +362,13 @@ struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void init_code_breakpoints(stlink_t *sl) {
 | 
					static void init_code_breakpoints(stlink_t *sl) {
 | 
				
			||||||
	memset(sl->q_buf, 0, 4);
 | 
						memset(sl->q_buf, 0, 4);
 | 
				
			||||||
	sl->q_buf[0] = 0x03; // KEY | ENABLE
 | 
						stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/);
 | 
				
			||||||
	stlink_write_mem32(sl, CM3_REG_FP_CTRL, 4);
 | 
					 | 
				
			||||||
        printf("KARL - should read back as 0x03, not 60 02 00 00\n");
 | 
					        printf("KARL - should read back as 0x03, not 60 02 00 00\n");
 | 
				
			||||||
        stlink_read_mem32(sl, CM3_REG_FP_CTRL, 4);
 | 
					        stlink_read_debug32(sl, CM3_REG_FP_CTRL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(sl->q_buf, 0, 4);
 | 
					 | 
				
			||||||
	for(int i = 0; i < CODE_BREAK_NUM; i++) {
 | 
						for(int i = 0; i < CODE_BREAK_NUM; i++) {
 | 
				
			||||||
		code_breaks[i].type = 0;
 | 
							code_breaks[i].type = 0;
 | 
				
			||||||
		stlink_write_mem32(sl, CM3_REG_FP_COMP0 + i * 4, 4);
 | 
							stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -416,28 +402,23 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) {
 | 
				
			||||||
	if(set) brk->type |= type;
 | 
						if(set) brk->type |= type;
 | 
				
			||||||
	else	brk->type &= ~type;
 | 
						else	brk->type &= ~type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(sl->q_buf, 0, 4);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(brk->type == 0) {
 | 
						if(brk->type == 0) {
 | 
				
			||||||
		#ifdef DEBUG
 | 
							#ifdef DEBUG
 | 
				
			||||||
		printf("clearing hw break %d\n", id);
 | 
							printf("clearing hw break %d\n", id);
 | 
				
			||||||
		#endif
 | 
							#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		stlink_write_mem32(sl, 0xe0002008 + id * 4, 4);
 | 
							stlink_write_debug32(sl, 0xe0002008 + id * 4, 0);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		sl->q_buf[0] = ( brk->addr        & 0xff) | 1;
 | 
						        uint32_t mask = (brk->addr) | 1 | (brk->type << 30);
 | 
				
			||||||
		sl->q_buf[1] = ((brk->addr >> 8)  & 0xff);
 | 
					 | 
				
			||||||
		sl->q_buf[2] = ((brk->addr >> 16) & 0xff);
 | 
					 | 
				
			||||||
		sl->q_buf[3] = ((brk->addr >> 24) & 0xff) | (brk->type << 6);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#ifdef DEBUG
 | 
							#ifdef DEBUG
 | 
				
			||||||
		printf("setting hw break %d at %08x (%d)\n",
 | 
							printf("setting hw break %d at %08x (%d)\n",
 | 
				
			||||||
			id, brk->addr, brk->type);
 | 
								id, brk->addr, brk->type);
 | 
				
			||||||
		printf("reg %02x %02x %02x %02x\n",
 | 
							printf("reg %08x \n",
 | 
				
			||||||
			sl->q_buf[3], sl->q_buf[2], sl->q_buf[1], sl->q_buf[0]);
 | 
								mask);
 | 
				
			||||||
		#endif
 | 
							#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		stlink_write_mem32(sl, 0xe0002008 + id * 4, 4);
 | 
							stlink_write_debug32(sl, 0xe0002008 + id * 4, mask);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,9 +405,9 @@ int stlink_load_device_params(stlink_t *sl) {
 | 
				
			||||||
      chip_id = 0x413;
 | 
					      chip_id = 0x413;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sl->chip_id = chip_id;
 | 
					    sl->chip_id = chip_id & 0xfff;
 | 
				
			||||||
	for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
 | 
						for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
 | 
				
			||||||
		if(devices[i].chip_id == (chip_id & 0xFFF)) {
 | 
							if(devices[i].chip_id == sl->chip_id) {
 | 
				
			||||||
			params = &devices[i];
 | 
								params = &devices[i];
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -422,9 +422,9 @@ int stlink_load_device_params(stlink_t *sl) {
 | 
				
			||||||
    sl->sram_base = STM32_SRAM_BASE;
 | 
					    sl->sram_base = STM32_SRAM_BASE;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // read flash size from hardware, if possible...
 | 
					    // read flash size from hardware, if possible...
 | 
				
			||||||
    if ((chip_id & 0xFFF) == STM32_CHIPID_F2) {
 | 
					    if (sl->chip_id == STM32_CHIPID_F2) {
 | 
				
			||||||
        sl->flash_size = 0; // FIXME - need to work this out some other way, just set to max possible?
 | 
					        sl->flash_size = 0; // FIXME - need to work this out some other way, just set to max possible?
 | 
				
			||||||
    } else if ((chip_id & 0xFFF) == STM32_CHIPID_F4) {
 | 
					    } else if (sl->chip_id == STM32_CHIPID_F4) {
 | 
				
			||||||
		sl->flash_size = 0x100000;			//todo: RM0090 error; size register same address as unique ID
 | 
							sl->flash_size = 0x100000;			//todo: RM0090 error; size register same address as unique ID
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0xffff;
 | 
					        uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0xffff;
 | 
				
			||||||
| 
						 | 
					@ -799,6 +799,11 @@ int stlink_fwrite_sram
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* success */
 | 
					    /* success */
 | 
				
			||||||
    error = 0;
 | 
					    error = 0;
 | 
				
			||||||
 | 
					    /* set stack*/
 | 
				
			||||||
 | 
					    stlink_write_reg(sl, stlink_read_debug32(sl, addr    ),13);
 | 
				
			||||||
 | 
					    /* Set PC to the reset routine*/
 | 
				
			||||||
 | 
					    stlink_write_reg(sl, stlink_read_debug32(sl, addr + 4),15);
 | 
				
			||||||
 | 
					    stlink_run(sl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
on_error:
 | 
					on_error:
 | 
				
			||||||
    unmap_file(&mf);
 | 
					    unmap_file(&mf);
 | 
				
			||||||
| 
						 | 
					@ -1048,26 +1053,45 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int stlink_erase_flash_mass(stlink_t *sl) {
 | 
					int stlink_erase_flash_mass(stlink_t *sl) {
 | 
				
			||||||
    /* wait for ongoing op to finish */
 | 
					     if (sl->chip_id == STM32_CHIPID_F4) {
 | 
				
			||||||
    wait_flash_busy(sl);
 | 
					        DLOG("(FIXME) Mass erase of STM32F4\n");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					     else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) {
 | 
				
			||||||
 | 
						 /* erase each page */
 | 
				
			||||||
 | 
						 int i = 0, num_pages = sl->flash_size/sl->flash_pgsz;
 | 
				
			||||||
 | 
						 for (i = 0; i < num_pages; i++) {
 | 
				
			||||||
 | 
						     /* addr must be an addr inside the page */
 | 
				
			||||||
 | 
						     stm32_addr_t addr = sl->flash_base + i * sl->flash_pgsz;
 | 
				
			||||||
 | 
						     if (stlink_erase_flash_page(sl, addr) == -1) {
 | 
				
			||||||
 | 
							 WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr);
 | 
				
			||||||
 | 
							 return -1;
 | 
				
			||||||
 | 
						     }
 | 
				
			||||||
 | 
						     fprintf(stdout,"\rFlash page at %5d/%5d erased", i, num_pages);
 | 
				
			||||||
 | 
						     fflush(stdout);
 | 
				
			||||||
 | 
						 }
 | 
				
			||||||
 | 
						 fprintf(stdout, "\n");
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					     else {
 | 
				
			||||||
 | 
						 /* wait for ongoing op to finish */
 | 
				
			||||||
 | 
						 wait_flash_busy(sl);
 | 
				
			||||||
	 
 | 
						 
 | 
				
			||||||
    /* unlock if locked */
 | 
						 /* unlock if locked */
 | 
				
			||||||
    unlock_flash_if(sl);
 | 
						 unlock_flash_if(sl);
 | 
				
			||||||
	 
 | 
						 
 | 
				
			||||||
    /* set the mass erase bit */
 | 
						 /* set the mass erase bit */
 | 
				
			||||||
    set_flash_cr_mer(sl);
 | 
						 set_flash_cr_mer(sl);
 | 
				
			||||||
	 
 | 
						 
 | 
				
			||||||
    /* start erase operation, reset by hw with bsy bit */
 | 
						 /* start erase operation, reset by hw with bsy bit */
 | 
				
			||||||
    set_flash_cr_strt(sl);
 | 
						 set_flash_cr_strt(sl);
 | 
				
			||||||
	 
 | 
						 
 | 
				
			||||||
    /* wait for completion */
 | 
						 /* wait for completion */
 | 
				
			||||||
    wait_flash_busy(sl);
 | 
						 wait_flash_busy(sl);
 | 
				
			||||||
	 
 | 
						 
 | 
				
			||||||
    /* relock the flash */
 | 
						 /* relock the flash */
 | 
				
			||||||
    lock_flash(sl);
 | 
						 lock_flash(sl);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* todo: verify the erased memory */
 | 
					 | 
				
			||||||
	 
 | 
						 
 | 
				
			||||||
 | 
						 /* todo: verify the erased memory */
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1185,7 +1209,7 @@ int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, unsigned length) {
 | 
					int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, unsigned length) {
 | 
				
			||||||
    size_t off;
 | 
					    size_t off;
 | 
				
			||||||
    if ((sl->chip_id & 0xFFF) == STM32_CHIPID_F4) {
 | 
					    if (sl->chip_id == STM32_CHIPID_F4) {
 | 
				
			||||||
        DLOG("(FIXME)Skipping verification for F4, not enough ram (yet)\n");
 | 
					        DLOG("(FIXME)Skipping verification for F4, not enough ram (yet)\n");
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1254,7 +1278,6 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns
 | 
				
			||||||
        while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) {
 | 
					        while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fprintf(stdout, "\n");
 | 
					 | 
				
			||||||
    val = stlink_read_debug32(sl, STM32L_FLASH_PECR);
 | 
					    val = stlink_read_debug32(sl, STM32L_FLASH_PECR);
 | 
				
			||||||
    val &= ~(1 << FLASH_L1_PROG);
 | 
					    val &= ~(1 << FLASH_L1_PROG);
 | 
				
			||||||
    stlink_write_debug32(sl, STM32L_FLASH_PECR, val);
 | 
					    stlink_write_debug32(sl, STM32L_FLASH_PECR, val);
 | 
				
			||||||
| 
						 | 
					@ -1386,16 +1409,29 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
 | 
				
			||||||
    		fprintf(stderr, "pecr.prglock not clear\n");
 | 
					    		fprintf(stderr, "pecr.prglock not clear\n");
 | 
				
			||||||
    		return -1;
 | 
					    		return -1;
 | 
				
			||||||
    	}
 | 
					    	}
 | 
				
			||||||
 | 
						off = 0;
 | 
				
			||||||
        if (len > L1_WRITE_BLOCK_SIZE) {
 | 
					        if (len > L1_WRITE_BLOCK_SIZE) {
 | 
				
			||||||
            if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1){
 | 
					            if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1){
 | 
				
			||||||
 | 
							/* This may happen on a blank device! */
 | 
				
			||||||
                WLOG("\nwrite_half_pages failed == -1\n");
 | 
					                WLOG("\nwrite_half_pages failed == -1\n");
 | 
				
			||||||
                return -1;
 | 
						    }
 | 
				
			||||||
            }
 | 
						    else{
 | 
				
			||||||
        }  
 | 
							off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    	/* write remainingword in program memory */
 | 
					    	/* write remainingword in program memory */
 | 
				
			||||||
    	for (off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; off < len; off += sizeof(uint32_t)) {
 | 
					    	for ( ; off < len; off += sizeof(uint32_t)) {
 | 
				
			||||||
    		uint32_t data;
 | 
					    		uint32_t data;
 | 
				
			||||||
 | 
							if (off > 254)
 | 
				
			||||||
 | 
							    fprintf(stdout, "\r");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) {
 | 
				
			||||||
 | 
							    fprintf(stdout, "\r%3u/%u pages written", 
 | 
				
			||||||
 | 
								    off/sl->flash_pgsz, len/sl->flash_pgsz);
 | 
				
			||||||
 | 
							    fflush(stdout);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    		write_uint32((unsigned char*) &data, *(uint32_t*) (base + off));
 | 
					    		write_uint32((unsigned char*) &data, *(uint32_t*) (base + off));
 | 
				
			||||||
    		stlink_write_debug32(sl, addr + off, data);
 | 
					    		stlink_write_debug32(sl, addr + off, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1514,6 +1550,11 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) {
 | 
				
			||||||
	mf.len -= num_empty;
 | 
						mf.len -= num_empty;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    err = stlink_write_flash(sl, addr, mf.base, mf.len);
 | 
					    err = stlink_write_flash(sl, addr, mf.base, mf.len);
 | 
				
			||||||
 | 
					    /* set stack*/
 | 
				
			||||||
 | 
					    stlink_write_reg(sl, stlink_read_debug32(sl, addr    ),13);
 | 
				
			||||||
 | 
					    /* Set PC to the reset routine*/
 | 
				
			||||||
 | 
					    stlink_write_reg(sl, stlink_read_debug32(sl, addr + 4),15);
 | 
				
			||||||
 | 
					    stlink_run(sl);
 | 
				
			||||||
    unmap_file(&mf);
 | 
					    unmap_file(&mf);
 | 
				
			||||||
    return err;
 | 
					    return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1562,12 +1603,12 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
 | 
				
			||||||
    stlink_run(sl);
 | 
					    stlink_run(sl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* wait until done (reaches breakpoint) */
 | 
					    /* wait until done (reaches breakpoint) */
 | 
				
			||||||
    while ((is_core_halted(sl) == 0) && (i <10000))
 | 
					    while ((is_core_halted(sl) == 0) && (i <1000))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        i++;
 | 
					        i++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( i > 9999) {
 | 
					    if ( i > 999) {
 | 
				
			||||||
        fprintf(stderr, "run error\n");
 | 
					        fprintf(stderr, "run error\n");
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -363,6 +363,7 @@ extern "C" {
 | 
				
			||||||
    int stlink_erase_flash_mass(stlink_t* sl);
 | 
					    int stlink_erase_flash_mass(stlink_t* sl);
 | 
				
			||||||
    int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, unsigned length);
 | 
					    int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, unsigned length);
 | 
				
			||||||
    int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr);
 | 
					    int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr);
 | 
				
			||||||
 | 
					    int stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr);
 | 
				
			||||||
    int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, unsigned length);
 | 
					    int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, unsigned length);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // PUBLIC
 | 
					    // PUBLIC
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Ładowanie…
	
		Reference in New Issue