示例#1
0
void stm32_flash_unlock(void)
{
  sem_lock();
  flash_unlock(STM32_FLASH_BANK0_BASE);
#if defined(STM32_FLASH_DUAL_BANK)
  flash_unlock(STM32_FLASH_BANK1_BASE);
#endif
  sem_unlock();
}
示例#2
0
/** Erase one sector starting at defined address
 *
 * The address should be at sector boundary. This function does not do any check for address alignments
 * @param obj The flash object
 * @param address The sector starting address
 * @return 0 for success, -1 for error
 */
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
{
    uint32_t number;
    sector_t sector_info;
    int32_t flash_state = 0;
    flash_unlock();

    /* clear FLASH flag */
    fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);

    /* make sure the address is a right page address */
    sector_info = flash_sector_info_get(address);
    if (11U >= sector_info.sector_num) {
        number = sector_info.sector_num;
    } else if (23U >= sector_info.sector_num) {
        number = sector_info.sector_num + 4U;
    } else {
        number = sector_info.sector_num - 12U;
    }
    if (FMC_READY != fmc_sector_erase(CTL_SN(number))) {
        flash_state = -1;
    }

    flash_lock();
    return flash_state;
}
示例#3
0
/** Program pages starting at defined address
 *
 * The pages should not cross multiple sectors.
 * This function does not do any check for address alignments or if size is aligned to a page size.
 * @param obj The flash object
 * @param address The sector starting address
 * @param data The data buffer to be programmed
 * @param size The number of bytes to program
 * @return 0 for success, -1 for error
 */
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
{
    uint32_t *p_data;
    p_data = (uint32_t *)data;
    uint32_t num = 0;
    int32_t flash_state = 0;
    flash_unlock();

    /* clear FLASH flag */
    fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);

    if (size % 4) {
        num = size / 4 + 1;
    } else {
        num = size / 4;
    }
    for (uint32_t i = 0; i < num; i++) {

        if (FMC_READY != fmc_word_program(address, *(p_data + i))) {
            flash_state = -1;
            break;
        }
        address += 4;
    }
    flash_lock();
    return flash_state;
}
示例#4
0
boolean DueFlash::write(uint32_t address, byte value) {
  uint32_t retCode;
  uint32_t byteLength = 1;  
  byte *data;

  retCode = flash_unlock((uint32_t)FLASH_START+address, (uint32_t)FLASH_START+address + byteLength - 1, 0, 0);
  if (retCode != FLASH_RC_OK) {
    _FLASH_DEBUG("Failed to unlock flash for write\n");
    return false;
  }

  // write data
  retCode = flash_write((uint32_t)FLASH_START+address, &value, byteLength, 1);
  //retCode = flash_write((uint32_t)FLASH_START, data, byteLength, 1);

  if (retCode != FLASH_RC_OK) {
    _FLASH_DEBUG("Flash write failed\n");
    return false;
  }

  // Lock page
  retCode = flash_lock((uint32_t)FLASH_START+address, (uint32_t)FLASH_START+address + byteLength - 1, 0, 0);
  if (retCode != FLASH_RC_OK) {
    _FLASH_DEBUG("Failed to lock flash page\n");
    return false;
  }
  return true;
}
示例#5
0
文件: isp.c 项目: kiibohd/controller
static void mem_flash_write(isp_addr_t dst, const void *src, uint16_t nbytes)
{
	uint32_t ul_rc;

	if (((dst - IFLASH0_ADDR) % LOCK_REGION_SIZE) == 0) {
		/* Unlock page */
		//ul_rc = flash_unlock(dst, dst+nbytes-1, 0, 0);
		ul_rc = flash_unlock(dst, dst+LOCK_REGION_SIZE-1, 0, 0);
		if (ul_rc != FLASH_RC_OK) {
			return;
		}

		/* The EWP command is not supported for non-8KByte sectors in all devices
		 *  SAM4 series, so an erase command is requried before the write operation.
		 */
		//ul_rc = flash_erase_sector(dst);
		ul_rc = flash_erase_page(dst, IFLASH_ERASE_PAGES_16);
		if (ul_rc != FLASH_RC_OK) {
			return;
		}
	}

	/* Write page */
	flash_write(dst, src, nbytes, 0);
}
示例#6
0
// Switch into boot mode and reset
void EraseAndReset()
{
	cpu_irq_disable();

#if SAM4S
# define IFLASH_ADDR				IFLASH0_ADDR
# define IFLASH_PAGE_SIZE			IFLASH0_PAGE_SIZE
# define IFLASH_NB_OF_PAGES			(IFLASH0_SIZE / IFLASH_PAGE_SIZE)
#endif

#if SAM3XA
# define IFLASH_ADDR				IFLASH0_ADDR
# define IFLASH_PAGE_SIZE			IFLASH0_PAGE_SIZE
# define IFLASH_NB_OF_PAGES			((IFLASH1_ADDR + IFLASH1_SIZE - IFLASH_ADDR) / IFLASH_PAGE_SIZE)
#endif

    for(size_t i = 0; i <= IFLASH_NB_OF_PAGES; i++)
    {
    	wdt_restart(WDT);
        size_t pageStartAddr = IFLASH_ADDR + i * IFLASH_PAGE_SIZE;
        flash_unlock(pageStartAddr, pageStartAddr + IFLASH_PAGE_SIZE - 1, nullptr, nullptr);
    }

    flash_clear_gpnvm(1);			// tell the system to boot from ROM next time
	rstc_start_software_reset(RSTC);
	for(;;) {}
}
示例#7
0
// Запись флага.
modbus_rtu_error_t boot_modbus_on_write_coil(uint16_t address, modbus_rtu_coil_value_t value)
{
    switch(address){
        default:
            return MODBUS_RTU_ERROR_INVALID_ADDRESS;
        case BOOT_MODBUS_COIL_PAGE_ERASE:
            if(value == MODBUS_RTU_COIL_ON){
                if(!flash_unlock()) return MODBUS_RTU_ERROR_NONRECOVERABLE;
                if(!flash_page_erase(flash_page_address(boot_modbus.page_number))){
                    flash_lock();
                    return MODBUS_RTU_ERROR_NONRECOVERABLE;
                }
                flash_lock();
            }
            break;
        case BOOT_MODBUS_COIL_RUN_APP:
            if(value == MODBUS_RTU_COIL_ON){
                if(!boot_modbus.run_app_callback) return MODBUS_RTU_ERROR_NONRECOVERABLE;
                boot_modbus.run_app_callback();
            }
            break;
    }
    
    return MODBUS_RTU_ERROR_NONE;
}
示例#8
0
void flash_write_struct(uint32_t address, uint8_t *struct_p, uint32_t size){
	uint16_t data=0;
	uint32_t i;

	flash_erase_page(params_addr);

	for(i=0; i<size; i+=2){
		if(i == (size-1) && (size % 2) != 0){
			data = 0xff;
			data = data << 8;
			data |= struct_p[i];
		}
		else{
			data = struct_p[i+1];
			data = data << 8;
			data |= struct_p[i];
		}

		flash_unlock();
		FLASH->CR |= FLASH_CR_PG; //Разрешаем программирование флеша
		while(!flash_ready()) //Ожидаем готовности флеша к записи
			;
		*(__IO uint16_t*)address = data; //Пишем младшие 2 бата
		while(!flash_ready())
			;
		FLASH->CR &= ~(FLASH_CR_PG); //Запрещаем программирование флеша
		FLASH->CR &= ~FLASH_CR_PER; //Сбрасываем бит обратно
		flash_lock();

		address+=2;
	}
}
示例#9
0
OSStatus internalFlashErase(uint32_t start_address, uint32_t end_address)
{
  platform_log_trace();
  uint32_t i;
  OSStatus err = kNoErr;
  uint32_t page_start_address, page_end_address;
  uint32_t page_start_number, page_end_number;

  platform_mcu_powersave_disable();

  require_action( flash_unlock( start_address, end_address, &page_start_address, &page_end_address ) == FLASH_RC_OK, exit, err = kGeneralErr );

  page_start_number = page_start_address/512;
  page_end_number   = page_end_address/512;
  require_action( page_end_number >= page_start_number + 16, exit, err = kUnsupportedErr);

  for ( i = page_start_number; i <= page_end_number; i+=16 )
  {
    require_action( flash_erase_page( i * 512, IFLASH_ERASE_PAGES_16) == FLASH_RC_OK, exit, err = kGeneralErr );
  }

  require_action( flash_lock( start_address, end_address, NULL, NULL ) == FLASH_RC_OK, exit, err = kGeneralErr );

exit:
  platform_mcu_powersave_enable();
  return err;
}
示例#10
0
void config_updateToFlash()
{

    uint16_t *dst = &_flashConfigROMBegin;
    uint16_t *src = &_flashConfigRAMBegin;

    bool canUpdateFlash = false;
    for (; src < &_flashConfigRAMEnd; ++src, ++dst)
    {
        if (*dst != *src)
        {
            canUpdateFlash = true;
            break;
        }
    }


    if (false != canUpdateFlash)
    {
        dst = &_flashConfigROMBegin;
        src = &_flashConfigRAMBegin;
        (void) flash_unlock();
        flash_erase_sector(FLASH_CONFIG_SECTOR, FLASH_PROGRAMM_ACCESS_SIZE);
        for (; src < &_flashConfigRAMEnd; ++src, ++dst)
        {
            flash_program_half_word((uint32_t)dst, *src, FLASH_PROGRAMM_ACCESS_SIZE);
        }
        (void) flash_lock();
    }
}
示例#11
0
文件: flash.c 项目: cilynx/dd-wrt
void
fis_update_directory(void)
{
    int stat;
    void *err_addr;

    fis_endian_fixup(fis_work_block);
#ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
    memcpy((char *)fis_work_block+fisdir_size, config, cfg_size);
    conf_endian_fixup((char *)fis_work_block+fisdir_size);
#endif
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
    // Ensure [quietly] that the directory is unlocked before trying to update
    flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr);
#endif
    if ((stat = flash_erase(fis_addr, flash_block_size, (void **)&err_addr)) != 0) {
        diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat));
    } else {
        if ((stat = FLASH_PROGRAM(fis_addr, fis_work_block,
                                  flash_block_size, (void **)&err_addr)) != 0) {
            diag_printf("Error writing FIS directory at %p: %s\n", 
                        err_addr, flash_errmsg(stat));
        }
    }
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
    // Ensure [quietly] that the directory is locked after the update
    flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr);
#endif
    fis_endian_fixup(fis_work_block);
}
示例#12
0
/* write a new configuration item to config space in flash memory.
 * data will be 4-byte aligned when writing, but original length information
 * will be retained.
 *
 * @return 0 if successful, -2 when no space for storing data is available,
 *         -1 when there is not enough space for the requested length
 */
int config_write(const uint32_t type, const uint32_t length, const void* data) {
	uint32_t *dst = (uint32_t*) config_find_item(CONFIG_UNSET);
	if(dst == NULL)
		return -2;
	if(dst + length + 3 >= (uint32_t*)(CONFIG_ADDRESS + CONFIG_SIZE))
		return -1;

	flash_unlock();
	/* write header information */
	flash_program_word((uint32_t)(dst++), type);
	flash_program_word((uint32_t)(dst++), length);
	/* word-wise reading/writing */
	uint32_t p = 0;
	for(; p + 3 < length; p+=sizeof(uint32_t)) {
		uint32_t v = *((uint32_t*)(data+p));
		flash_program_word((uint32_t)(dst++), v);
	}
	/* read remainder of partial last word */
	if(p < length) {
		uint32_t v = ((uint8_t*)data)[p++];
		if(p < length)
			v = v | (((uint8_t*)data)[p++] << 8);
		if(p < length)
			v = v | (((uint8_t*)data)[p++] << 16);
		flash_program_word((uint32_t)(dst++), v);
	}
	flash_lock();
	return 0;
}
示例#13
0
/* erase complete configuration store */
void config_erase(void) {
	flash_unlock();
	for(void *config = (void*)CONFIG_ADDRESS; config < (void*)(CONFIG_ADDRESS + CONFIG_SIZE); config += FLASH_PAGE_SIZE) {
		flash_erase_page((uint32_t)config);
	}
	flash_lock();
}
示例#14
0
static void fis_update_directory(void)
{
    int stat;
    void *err_addr;
	
#ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
    memcpy((char *)fis_work_block+fisdir_size, config, cfg_size);
#endif
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
    // Ensure [quietly] that the directory is unlocked before trying to update
    flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr);
#endif
    if ((stat = fis_flash_erase(fis_addr, flash_block_size, (void **)&err_addr)) != 0) {
		SYS_DEBUG(SYSDEBUG_TRACE_FIS, "Error erasing FIS directory at %p: %s\n\r", err_addr, flash_errmsg(stat));
    } else {
        if ((stat = fis_flash_program(fis_addr, fis_work_block, flash_block_size,
								  (void **)&err_addr)) != 0) {
			SYS_DEBUG(SYSDEBUG_TRACE_FIS, "Error writing FIS directory at %p: %s\n\r", 
							   err_addr, flash_errmsg(stat));
        }
    }
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
    // Ensure [quietly] that the directory is locked after the update
    flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr);
#endif
}
示例#15
0
void CopyPatchToFlash(void) {
  flash_unlock();
  flash_Erase_sector(11);
  int src_addr = PATCHMAINLOC;
  int flash_addr = PATCHFLASHLOC;
  int c;
  for (c = 0; c < PATCHFLASHSIZE;) {
    flash_ProgramWord(flash_addr, *(int32_t *)src_addr);
    src_addr += 4;
    flash_addr += 4;
    c += 4;
  }
  // verify
  src_addr = PATCHMAINLOC;
  flash_addr = PATCHFLASHLOC;
  int err = 0;
  for (c = 0; c < PATCHFLASHSIZE;) {
    if (*(int32_t *)flash_addr != *(int32_t *)src_addr)
      err++;
    src_addr += 4;
    flash_addr += 4;
    c += 4;
  }
  if (err) {
    while (1) {
      // flash verify fail
    }
  }
  AckPending = 1;
}
示例#16
0
文件: storage.c 项目: hno/trezor-mcu
void storage_commit(void)
{
	int i;
	uint32_t *w;
	// backup meta
	memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN);
	flash_clear_status_flags();
	flash_unlock();
	// erase storage
	for (i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) {
		flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
	}
	// modify storage
	memcpy(meta_backup + FLASH_META_DESC_LEN, "stor", 4);
	memcpy(meta_backup + FLASH_META_DESC_LEN + 4, storage_uuid, sizeof(storage_uuid));
	memcpy(meta_backup + FLASH_META_DESC_LEN + 4 + sizeof(storage_uuid), &storage, sizeof(Storage));
	// copy it back
	for (i = 0; i < FLASH_META_LEN / 4; i++) {
		w = (uint32_t *)(meta_backup + i * 4);
		flash_program_word(FLASH_META_START + i * 4, *w);
	}
	flash_lock();
	// flash operation failed
	if (FLASH_SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_WRPERR)) {
		layoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Storage failure", "detected.", NULL, "Please unplug", "the device.", NULL);
		for (;;) { }
	}
}
示例#17
0
static int32_t pflash_program_bytes(struct FlashInfo* flash,
                    uint32_t   src,
                    uint32_t   size,
                    uint32_t   chksum) {
  uint32_t i;

  /* erase */
  flash_unlock();
  flash_erase_page(flash->addr);
  flash_lock();

  /* verify erase */
  for (i=0; i<flash->page_size; i+=4) {
    if ((*(uint32_t*) (flash->addr + i)) != 0xFFFFFFFF) return -1;
  }

  flash_unlock();
  /* write full 16 bit words */
  for (i=0; i<(size & ~1); i+=2) {
    flash_program_half_word(flash->addr+i,
        (uint16_t)(*(uint8_t*)(src+i) | (*(uint8_t*)(src+i+1)) << 8));
  }
  /* fill bytes with a zero */
  if (size & 1) {
    flash_program_half_word(flash->addr+i, (uint16_t)(*(uint8_t*)(src+i)));
  }
  /* write size */
  flash_program_half_word(flash->addr+flash->page_size-FSIZ,
                          (uint16_t)(size & 0xFFFF));
  flash_program_half_word(flash->addr+flash->page_size-FSIZ+2,
                          (uint16_t)((size >> 16) & 0xFFFF));
  /* write checksum */
  flash_program_half_word(flash->addr+flash->page_size-FCHK,
                          (uint16_t)(chksum & 0xFFFF));
  flash_program_half_word(flash->addr+flash->page_size-FCHK+2,
                          (uint16_t)((chksum >> 16) & 0xFFFF));
  flash_lock();

  /* verify data */
  for (i=0; i<size; i++) {
    if ((*(uint8_t*) (flash->addr+i)) != (*(uint8_t*) (src+i))) return -2;
  }
  if (*(uint32_t*) (flash->addr+flash->page_size-FSIZ) != size) return -3;
  if (*(uint32_t*) (flash->addr+flash->page_size-FCHK) != chksum) return -4;

  return 0;
}
void aseba_flash_erase_page(int aseba_page)
{
    flash_unlock();
    int sector = aseba_page_sector(aseba_page);
    if (sector != -1) { // first page in sector
        flash_erase_sector(sector, FLASH_CR_PROGRAM_X16);
    }
}
示例#19
0
文件: flash.c 项目: 0xCA5A/dd-wrt
int clear_all_lock_bits(ADDR addr)
{
    void *err_addr;
    int stat;

    if ((stat = flash_unlock((void *)0, eeprom_size, (void **)&err_addr)) != 0)
	return stat;
    return OK;
}
示例#20
0
//Функция стирает одну страницу. В качестве адреса можно использовать любой
//принадлежащий диапазону адресов той странице которую нужно очистить.
void flash_erase_page(uint32_t address) {
    flash_unlock();
    FLASH->CR|= FLASH_CR_PER; //Устанавливаем бит стирания одной страницы
    FLASH->AR = address; // Задаем её адрес
    FLASH->CR|= FLASH_CR_STRT; // Запускаем стирание 
    while(!flash_ready())
        ;  //Ждем пока страница сотрется. 
    FLASH->CR&= ~FLASH_CR_PER; //Сбрасываем бит обратно
    flash_lock();
}
示例#21
0
/**
 * \brief 
 * 
 * \param 
 * 
 * \return void
 */
void f_config_handle(void)
{
	uint32_t ul_last_page_addr = LAST_PAGE_ADDRESS;
	uint32_t *pul_last_page = (uint32_t *) ul_last_page_addr;
	uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
	uint32_t unique_id[4];
	
	memset( &f_ip_config, 0, sizeof(f_ip_config_t) );
	
	/* Initialize flash: 6 wait states for flash writing. */
	flash_init(FLASH_ACCESS_MODE_128, 6);
	
	/* Unlock page */
	flash_unlock(ul_last_page_addr, ul_last_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	
	/* Read Flash page */
	memcpy((uint8_t*)(&f_ip_config), (uint8_t*)pul_last_page, sizeof(f_ip_config_t));
	
	flash_read_unique_id(unique_id, 4);							/* read unique ID. */
	
	f_ip_config.mac[0]   = ETHERNET_CONF_ETHADDR0;
	f_ip_config.mac[1]   = ETHERNET_CONF_ETHADDR1;
	f_ip_config.mac[2]   = ETHERNET_CONF_ETHADDR2;
	f_ip_config.mac[3]   = ETHERNET_CONF_ETHADDR3;
	f_ip_config.mac[4]   = unique_id[3]>>8;
	f_ip_config.mac[5]   = unique_id[3];
	
	f_ip_config.mask[0]  = ETHERNET_CONF_NET_MASK0;
	f_ip_config.mask[1]  = ETHERNET_CONF_NET_MASK1;
	f_ip_config.mask[2]  = ETHERNET_CONF_NET_MASK2;
	f_ip_config.mask[3]  = ETHERNET_CONF_NET_MASK3;
	
	if (( f_ip_config.alloc != IP_CONFIG_ALLOC_TRUE ) ||
			 ( gpio_pin_is_low(RESTKEY_GPIO) == 1 ))			/* net parameters init. */
	{
		
		f_ip_config.mode     = IP_CONFIG_MODE_FIXEDIP;
		
		f_ip_config.alloc    = IP_CONFIG_ALLOC_TRUE;			/* net parameters are occupied.. */
		
		f_ip_config.ip[0]	 = ETHERNET_CONF_IPADDR0;
		f_ip_config.ip[1]	 = ETHERNET_CONF_IPADDR1;
		f_ip_config.ip[2]	 = ETHERNET_CONF_IPADDR2;
		f_ip_config.ip[3]    = ETHERNET_CONF_IPADDR3;
		
		/* Copy information to FLASH buffer..*/
		memcpy((uint8_t*)ul_page_buffer, (uint8_t *)(&f_ip_config), sizeof(f_ip_config_t));
		
		/* Write page */
		flash_write(ul_last_page_addr, ul_page_buffer, IFLASH_PAGE_SIZE, 1);
	}
	
	/* Lock page */
	flash_lock(ul_last_page_addr, ul_last_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
}
示例#22
0
void check_bootloader(void)
{
#if MEMORY_PROTECT
	uint8_t hash[32];
	int r = memory_bootloader_hash(hash);

	if (!known_bootloader(r, hash)) {
		layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Unknown bootloader"), _("detected."), NULL, _("Unplug your TREZOR"), _("contact our support."), NULL);
		shutdown();
	}

	if (is_mode_unprivileged()) {
		return;
	}

	if (r == 32 && 0 == memcmp(hash, bl_hash, 32)) {
		// all OK -> done
		return;
	}

	// ENABLE THIS AT YOUR OWN RISK
	// ATTEMPTING TO OVERWRITE BOOTLOADER WITH UNSIGNED FIRMWARE MAY BRICK
	// YOUR DEVICE.

	layoutDialog(&bmp_icon_warning, NULL, NULL, NULL, _("Updating bootloader"), NULL, NULL, _("DO NOT UNPLUG"), _("YOUR TREZOR!"), NULL);

	// unlock sectors
	memory_write_unlock();

	for (int tries = 0; tries < 10; tries++) {
		// replace bootloader
		flash_unlock();
		for (int i = FLASH_BOOT_SECTOR_FIRST; i <= FLASH_BOOT_SECTOR_LAST; i++) {
			flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
		}
		for (int i = 0; i < FLASH_BOOT_LEN / 4; i++) {
			const uint32_t *w = (const uint32_t *)(bl_data + i * 4);
			flash_program_word(FLASH_BOOT_START + i * 4, *w);
		}
		flash_lock();
		// check whether the write was OK
		r = memory_bootloader_hash(hash);
		if (r == 32 && 0 == memcmp(hash, bl_hash, 32)) {
			// OK -> show info and halt
			layoutDialog(&bmp_icon_info, NULL, NULL, NULL, _("Update finished"), _("successfully."), NULL, _("Please reconnect"), _("the device."), NULL);
			shutdown();
			return;
		}
	}
	// show info and halt
	layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Bootloader update"), _("broken."), NULL, _("Unplug your TREZOR"), _("contact our support."), NULL);
	shutdown();
#endif
}
示例#23
0
void dfu_protect(dfu_mode_t mode)
{
    if (mode == DFU_MODE) {
#ifdef DFU_SELF_PROTECT
	if ((FLASH_WRPR & 0x03) != 0x00) {
		flash_unlock();
		FLASH_CR = 0;
		flash_erase_option_bytes();
		flash_program_option_bytes(FLASH_OBP_RDP, FLASH_OBP_RDP_KEY);
		/* CL Device: Protect 2 bits with (2 * 2k pages each)*/
		/* MD Device: Protect 2 bits with (4 * 1k pages each)*/
		flash_program_option_bytes(FLASH_OBP_WRP10, 0x03FC);
	}
#endif
    }
    else if (mode == UPD_MODE) {
		flash_unlock();
		FLASH_CR = 0;
		flash_erase_option_bytes();
    }
}
示例#24
0
bool FlashStorage::write(uint32_t address, const void *data, uint32_t dataLength)
{
	if ((uint32_t)FLASH_START + address < (uint32_t)&__flash_start__)
	{
		FLASH_DEBUG("Flash write address too low");
		return false;
	}

	if ((uint32_t)FLASH_START + address + dataLength > (uint32_t)&__flash_end__)
	{
		FLASH_DEBUG("Flash write address too high");
		return false;
	}

	if ((((uint32_t)FLASH_START + address) & 3) != 0)
	{
		FLASH_DEBUG("Flash start address must be on 4-byte boundary\n");
		return false;
	}

	// The flash management code in the ASF is fragile and has a tendency to fail to return. Help it by disabling interrupts.
	efc_disable_frdy_interrupt(EFC);								// should not be enabled already, but disable it just in case
	irqflags_t flags = cpu_irq_save();

	// Unlock page
	uint32_t retCode = flash_unlock((uint32_t)FLASH_START + address, (uint32_t)FLASH_START + address + dataLength - 1, NULL, NULL);
	if (retCode != FLASH_RC_OK)
	{
		FLASH_DEBUG("Failed to unlock flash for write");
	}
	else
	{
		// Write data
		retCode = flash_write((uint32_t)FLASH_START + address, data, dataLength, 1);
		if (retCode != FLASH_RC_OK)
		{
			FLASH_DEBUG("Flash write failed");
		}
		else
		{
			// Lock page
			retCode = flash_lock((uint32_t)FLASH_START + address, (uint32_t)FLASH_START + address + dataLength - 1, NULL, NULL);
			if (retCode != FLASH_RC_OK)
			{
				FLASH_DEBUG("Failed to lock flash page");
			}
		}
	}

	cpu_irq_restore(flags);
	return retCode == FLASH_RC_OK;
}
示例#25
0
flash_err_t
flash_write(const void *addr, const void *data, int len_in_bytes)
{
	flash_err_t err;

	if (RV_SUCCESS != flash_lock()) {
		return FLASH_ERR_PROTOCOL;
	}
	err = flash_write_sector_locked(addr, data, len_in_bytes);
	flash_unlock();

	return err;
}
示例#26
0
static flash_err_t
flash_erase_sectorinfo(const sector_info_t *sinfo)
{
	flash_err_t err;

	if (RV_SUCCESS != flash_lock()) {
		return FLASH_ERR_PROTOCOL;
	}
	err = flash_erase_sectorinfo_locked(sinfo);
	flash_unlock();

	return err;
}
示例#27
0
flash_result_t flash_program_word(const uint32_t *address, const uint32_t data)
{
  flash_unlock();
  if (FLASH_FAIL == flash_wait_for_idle())
    return FLASH_FAIL;
  FLASH->CR |= FLASH_CR_PG; // set the programming bit
  FLASH->CR &= ~FLASH_CR_PSIZE; // wipe out PSIZE to get ready to set it
  FLASH->CR |=  FLASH_CR_PSIZE_1; // we'll do 32-bit erases at a time
  *((volatile uint32_t *)address) = data;
  flash_result_t result = flash_wait_for_idle();
  FLASH->CR &= ~FLASH_CR_PG; // disable the programming bit
  //flash_lock();
  return result;
}
示例#28
0
void dfu_protect_enable(void)
{
#ifdef DFU_SELF_PROTECT
	if ((FLASH_WRPR & 0x03) != 0x00) {
		flash_unlock();
		FLASH_CR = 0;
		flash_erase_option_bytes();
		flash_program_option_bytes(FLASH_OBP_RDP, FLASH_OBP_RDP_KEY);
		/* CL Device: Protect 2 bits with (2 * 2k pages each)*/
		/* MD Device: Protect 2 bits with (4 * 1k pages each)*/
		flash_program_option_bytes(FLASH_OBP_WRP10, 0x03FC);
	}
#endif
}
示例#29
-1
/** Program one page starting at defined address
 *
 * The page should be at page boundary, should not cross multiple sectors.
 * This function does not do any check for address alignments or if size
 * is aligned to a page size.
 * @param obj The flash object
 * @param address The sector starting address
 * @param data The data buffer to be programmed
 * @param size The number of bytes to program
 * @return 0 for success, -1 for error
 */
int32_t flash_program_page(flash_t *obj, uint32_t address,
        const uint8_t *data, uint32_t size)
{
    uint32_t StartAddress = 0;
    int32_t status = 0;

    if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
        return -1;
    }

    if ((size % 8) != 0) {
        /* L4 flash devices can only be programmed 64bits/8 bytes at a time */
        return -1;
    }

    if (flash_unlock() != HAL_OK) {
        return -1;
    }

    /* Program the user Flash area word by word */
    StartAddress = address;

    /*  HW needs an aligned address to program flash, which data
     *  parameters doesn't ensure  */
    if ((uint32_t) data % 4 != 0) {
        volatile uint64_t data64;
        while ((address < (StartAddress + size)) && (status == 0)) {
            for (uint8_t i =0; i < 8; i++) {
                *(((uint8_t *) &data64) + i) = *(data + i);
            }

            if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data64)
                    == HAL_OK) {
                address = address + 8;
                data = data + 8;
            } else {
                status = -1;
            }
        }
    } else { /*  case where data is aligned, so let's avoid any copy */
        while ((address < (StartAddress + size)) && (status == 0)) {
            if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address,
                        *((uint64_t*) data))
                    == HAL_OK) {
                address = address + 8;
                data = data + 8;
            } else {
                status = -1;
            }
        }
    }

    flash_lock();

    return status;
}
示例#30
-1
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
{
    uint32_t StartAddress = 0;
    int32_t status = 0;

    if (!(IS_FLASH_PROGRAM_ADDRESS(address))) {
        return -1;
    }

    if ((size % MIN_PROG_SIZE) != 0) {
        return -1;
    }

    if (flash_unlock() != HAL_OK) {
        return -1;
    }

    /* Program the user Flash area word by word */
    StartAddress = address;

    /* HW needs an aligned address to program flash, which data parameter doesn't ensure */
    if ((uint32_t) data % 4 != 0) {

        volatile uint32_t data32;
        while (address < (StartAddress + size) && (status == 0)) {
            for (uint8_t i = 0; i < MIN_PROG_SIZE; i++) {
                *(((uint8_t *) &data32) + i) = *(data + i);
            }

            if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data32) == HAL_OK) {
                address = address + MIN_PROG_SIZE;
                data = data + MIN_PROG_SIZE;
            } else {
                status = -1;
            }
        }
    } else { /*  case where data is aligned, so let's avoid any copy */
        while ((address < (StartAddress + size)) && (status == 0)) {
            if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
                address = address + MIN_PROG_SIZE;
                data = data + MIN_PROG_SIZE;
            } else {
                status = -1;
            }
        }
    }

    flash_lock();

    return status;
}