示例#1
0
int do_flash_erase(uint32_t addr, uint32_t len) {
  if (addr % FLASH_SECTOR_SIZE != 0) return 0x32;
  if (len % FLASH_SECTOR_SIZE != 0) return 0x33;
  if (SPIUnlock() != 0) return 0x34;

  while (len > 0 && (addr % FLASH_BLOCK_SIZE != 0)) {
    if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35;
    len -= FLASH_SECTOR_SIZE;
    addr += FLASH_SECTOR_SIZE;
  }

  while (len > FLASH_BLOCK_SIZE) {
    if (SPIEraseBlock(addr / FLASH_BLOCK_SIZE) != 0) return 0x36;
    len -= FLASH_BLOCK_SIZE;
    addr += FLASH_BLOCK_SIZE;
  }

  while (len > 0) {
    if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37;
    len -= FLASH_SECTOR_SIZE;
    addr += FLASH_SECTOR_SIZE;
  }

  return 0;
}
示例#2
0
//extern char _text_end;
//=============================================================================
// IRAM code
//=============================================================================
// call_user_start() - вызов из заголовка, загрузчиком
// ENTRY(call_user_start) in eagle.app.v6.ld
//-----------------------------------------------------------------------------
void __attribute__ ((noreturn)) call_user_start(void)
{
//		Cache_Read_Disable();
		IO_RTC_4 = 0; // Отключить блок WiFi (уменьшение потребления на время загрузки)
		GPIO0_MUX_alt = VAL_MUX_GPIO0_SDK_DEF; // Отключить вывод CLK на GPIO0
		SPI0_USER |= SPI_CS_SETUP; // +1 такт перед CS = 0x80000064
#if FQSPI == 80	// xSPI на 80 MHz
		GPIO_MUX_CFG_alt |= BIT(MUX_SPI0_CLK_BIT); // QSPI = 80 MHz
		SPI0_CTRL = (SPI0_CTRL & SPI_CTRL_F_MASK) | SPI_CTRL_F80MHZ;
#else			// xSPI на 40 MHz
		GPIO_MUX_CFG_alt &= ~(1<< MUX_SPI0_CLK_BIT);
		SPI0_CTRL = (SPI0_CTRL & SPI_CTRL_F_MASK) | SPI_CTRL_F40MHZ;
#endif
		// OTA
#if DEBUGSOO > 1
		p_printf("\nStart OTA loader.\n");
#endif
		uint32_t buffer[SPI_FLASH_SEC_SIZE/4];
		SPIRead(esp_init_data_default_addr + MAX_SYS_CONST_BLOCK, buffer, (sizeof(OTA_flash_struct)+3)&~3);
		OTA_flash_struct *OTA = (OTA_flash_struct *)buffer;
		if(OTA->id == OTA_flash_struct_id) {
			uint32 image_start = OTA->image_addr;
			uint32 sectors = OTA->image_sectors;
			SPIRead(image_start, buffer, 4);
			if(*(uint8 *)buffer == firmware_start_magic) {
#if DEBUGSOO > 0
				p_printf("Update firmware from 0x%x, %u sectors: ", image_start, sectors);
#endif
				ets_delay_us(1000000); // 1 sec
				uint32 write_to = 0;
				for(uint32 i = 0; i < sectors; i++) {
					SPIRead(image_start + i * SPI_FLASH_SEC_SIZE, buffer, SPI_FLASH_SEC_SIZE);
					SPIEraseSector(i);
					SPIWrite(write_to, buffer, SPI_FLASH_SEC_SIZE);
					write_to += SPI_FLASH_SEC_SIZE;
#if DEBUGSOO > 0
					p_printf("x");
#endif
				}
#if DEBUGSOO > 0
				p_printf("\nOk.");
#endif
				if(image_start >= write_to) SPIEraseSector(image_start / SPI_FLASH_SEC_SIZE);
				_ResetVector();
			}
		}
#if DEBUGSOO > 1
		p_printf("\nGoto next loader.\n");
#endif
		// Всё, включаем кеширование, далее можно вызывать процедуры из flash
		Cache_Read_Enable(0, 0, 0);
		// Переход в область кеширования flash,
		// Запускаем загрузку SDK с указателем на заголовок SPIFlashHeader (находится за данным загручиком по адресу с align 16)
//		((loader_call)((uint32)(&loader_flash_boot) + FLASH_BASE - IRAM_BASE + 0x10))((struct SPIFlashHeader *)(((uint32)(&_text_end) + FLASH_BASE - IRAM_BASE + 0x17) & (~15)));
		((loader_call)(loader_flash_boot_addr))((struct SPIFlashHeader *)(next_flash_header_addr));
}
示例#3
0
文件: eboot.c 项目: 2thetop/Arduino
int copy_raw(const uint32_t src_addr,
             const uint32_t dst_addr,
             const uint32_t size)
{
    // require regions to be aligned
    if (src_addr & 0xfff != 0 ||
        dst_addr & 0xfff != 0) {
        return 1;
    }

    const uint32_t buffer_size = FLASH_SECTOR_SIZE;
    uint8_t buffer[buffer_size];
    uint32_t left = ((size+buffer_size-1) & ~(buffer_size-1));
    uint32_t saddr = src_addr;
    uint32_t daddr = dst_addr;

    while (left) {
        if (SPIEraseSector(daddr/buffer_size)) {
            return 2;
        }
        if (SPIRead(saddr, buffer, buffer_size)) {
            return 3;
        }
        if (SPIWrite(daddr, buffer, buffer_size)) {
            return 4;
        }
        saddr += buffer_size;
        daddr += buffer_size;
        left  -= buffer_size;
    }

    return 0;
}
示例#4
0
void load_app(uint32 from_addr, uint32 to_addr, uint32 total_size)
{
	uint8 buffer[SECTOR_SIZE];
	uint32 readpos, writepos, sector = to_addr/SECTOR_SIZE;
	readpos = from_addr;
	writepos = to_addr;
	while(total_size > 0) {
		INFO(".");
		SPIEraseSector(sector);
		if (SPIRead(readpos, buffer, SECTOR_SIZE) != 0) {
			return;
		}
		//INFO("ESPBOOT: Write at 0x%X ...\r\n", writepos);
		if (SPIWrite(writepos, buffer, SECTOR_SIZE) != 0) {
			return;
		}
		writepos += SECTOR_SIZE;
		readpos += SECTOR_SIZE;
		if(total_size > SECTOR_SIZE)
			total_size -= SECTOR_SIZE;
		else
			total_size = 0;
		sector ++;
	}
	INFO(".\r\n");
}
示例#5
0
int do_flash_write(uint32_t addr, uint32_t len, uint32_t erase) {
  struct uart_buf ub;
  uint8_t digest[16];
  uint32_t num_written = 0, num_erased = 0;
  struct MD5Context ctx;
  MD5Init(&ctx);

  if (addr % FLASH_SECTOR_SIZE != 0) return 0x32;
  if (len % FLASH_SECTOR_SIZE != 0) return 0x33;
  if (SPIUnlock() != 0) return 0x34;

  ub.nr = 0;
  ub.pr = ub.pw = ub.data;
  ets_isr_attach(ETS_UART_INUM, uart_isr, &ub);
  SET_PERI_REG_MASK(UART_INT_ENA(0), UART_RX_INTS);
  ets_isr_unmask(1 << ETS_UART_INUM);

  SLIP_send(&num_written, 4);

  while (num_written < len) {
    volatile uint32_t *nr = &ub.nr;
    /* Prepare the space ahead. */
    while (erase && num_erased < num_written + SPI_WRITE_SIZE) {
      const uint32_t num_left = (len - num_erased);
      if (num_left > FLASH_BLOCK_SIZE && addr % FLASH_BLOCK_SIZE == 0) {
        if (SPIEraseBlock(addr / FLASH_BLOCK_SIZE) != 0) return 0x35;
        num_erased += FLASH_BLOCK_SIZE;
      } else {
        /* len % FLASH_SECTOR_SIZE == 0 is enforced, no further checks needed */
        if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x36;
        num_erased += FLASH_SECTOR_SIZE;
      }
    }
    /* Wait for data to arrive. */
    while (*nr < SPI_WRITE_SIZE) {
    }
    MD5Update(&ctx, ub.pr, SPI_WRITE_SIZE);
    if (SPIWrite(addr, ub.pr, SPI_WRITE_SIZE) != 0) return 0x37;
    ets_intr_lock();
    *nr -= SPI_WRITE_SIZE;
    ets_intr_unlock();
    num_written += SPI_WRITE_SIZE;
    addr += SPI_WRITE_SIZE;
    ub.pr += SPI_WRITE_SIZE;
    if (ub.pr >= ub.data + UART_BUF_SIZE) ub.pr = ub.data;
    SLIP_send(&num_written, 4);
  }

  ets_isr_mask(1 << ETS_UART_INUM);

  MD5Final(digest, &ctx);
  SLIP_send(digest, 16);

  return 0;
}
示例#6
0
void save_boot_cfg(espboot_cfg *cfg)
{
	cfg->chksum = calc_chksum((uint8*)cfg, (uint8*)&cfg->chksum);
	if (SPIEraseSector(BOOT_CONFIG_SECTOR) != 0)
	{
		ERROR("Can not erase boot configuration sector\r\n");
	}
	if (SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, cfg, sizeof(espboot_cfg)) != 0)
	{
			ERROR("Can not save boot configurations\r\n");
	}
}
示例#7
0
文件: main.c 项目: ReneHerthel/RIOT
SpiFlashOpResult IRAM spi_flash_erase_sector(uint16_t sec)
{
    CHECK_PARAM_RET (sec < flashchip->chip_size / flashchip->sector_size, SPI_FLASH_RESULT_ERR);

    critical_enter ();
    Cache_Read_Disable();

    SpiFlashOpResult ret = SPIEraseSector (sec);

    Cache_Read_Enable(0, 0, 1);
    critical_exit ();

    return ret;
}
示例#8
0
void TWLCard::eraseSaveData(void (*cb)(u32, u32)) const {
	u32 pos;
	u32 sz = SPIGetCapacity(cardType_);
	Result res;
	
	cb(0, sz);

	for(pos = 0; pos < sz; pos += 0x10000) {
		res = SPIEraseSector(cardType_, pos);
		if(res != 0) throw Error(res, __FILE__, __LINE__);
		cb((sz < pos + 0x10000) ? sz : pos + 0x10000, sz);
	}
	
	
}
示例#9
0
// prevent this function being placed inline with main
// to keep main's stack size as small as possible
static uint32 NOINLINE find_image() {
	
	uint8 flag;
	uint32 runAddr;
	uint32 flashsize;
	int32 romToBoot;
	uint8 gpio_boot = FALSE;
	uint8 updateConfig = TRUE;
	uint8 buffer[SECTOR_SIZE];
	
	rboot_config *romconf = (rboot_config*)buffer;
	rom_header *header = (rom_header*)buffer;
	
	ets_delay_us(2000000);
	
	ets_printf("\r\nrBoot v1.0.0 - [email protected]\r\n");
	
	// read rom header
	SPIRead(0, header, sizeof(rom_header));
	
	// print and get flash size
	ets_printf("Flash Size:	 ");
	flag = header->flags2 >> 4;
	if (flag == 0) {
		ets_printf("4 Mbit\r\n");
		flashsize = 0x80000;
	} else if (flag == 1) {
		ets_printf("2 Mbit\r\n");
		flashsize = 0x40000;
	} else if (flag == 2) {
		ets_printf("8 Mbit\r\n");
		flashsize = 0x100000;
	} else if (flag == 3) {
		ets_printf("16 Mbit\r\n");
		flashsize = 0x200000;
	} else if (flag == 4) {
		ets_printf("32 Mbit\r\n");
		flashsize = 0x400000;
	} else {
		ets_printf("unknown\r\n");
		// assume at least 4mbit
		flashsize = 0x80000;
	}
	
	// print spi mode
	ets_printf("Flash Mode:	 ");
	if (header->flags1 == 0) {
		ets_printf("QIO\r\n");
	} else if (header->flags1 == 1) {
		ets_printf("QOUT\r\n");
	} else if (header->flags1 == 2) {
		ets_printf("DIO\r\n");
	} else if (header->flags1 == 3) {
		ets_printf("DOUT\r\n");
	} else {
		ets_printf("unknown\r\n");
	}
	
	// print spi speed
	ets_printf("Flash Speed: ");
	flag = header->flags2 & 0x0f;
	if (flag == 0) ets_printf("40 MHz\r\n");
	else if (flag == 1) ets_printf("26.7 MHz\r\n");
	else if (flag == 2) ets_printf("20 MHz\r\n");
	else if (flag == 0x0f) ets_printf("80 MHz\r\n");
	else ets_printf("unknown\r\n");
	
	// read boot config
	SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	// fresh install or old version?
	if (romconf->magic != BOOT_CONFIG_MAGIC || romconf->version != BOOT_CONFIG_VERSION) {
		// create a default config for a standard 2 rom setup
		ets_printf("Writing default boot config.\r\n");
		ets_memset(romconf, 0x00, sizeof(rboot_config));
		romconf->magic = BOOT_CONFIG_MAGIC;
		romconf->version = BOOT_CONFIG_VERSION;
		romconf->mode = MODE_STANDARD;
		romconf->current_rom = 0;
		romconf->count = 2;
		romconf->current_rom = 0;
		romconf->roms[0] = SECTOR_SIZE * 2;
		romconf->roms[1] = (flashsize / 2) + (SECTOR_SIZE * 2);
		// write new config sector
		SPIEraseSector(BOOT_CONFIG_SECTOR);
		SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	}
	
	// if gpio mode enabled check status of the gpio
	if ((romconf->mode & MODE_GPIO_ROM) && (get_gpio16() == 0)) {
		ets_printf("Booting GPIO-selected.\r\n");
		romToBoot = romconf->gpio_rom;
		gpio_boot = TRUE;
	} else if (romconf->current_rom >= romconf->count) {
		// if invalid rom selected try rom 0
		ets_printf("Invalid rom selected, defaulting.\r\n");
		romToBoot = 0;
		romconf->current_rom = 0;
		updateConfig = TRUE;
	} else {
		// try rom selected in the config
		romToBoot = romconf->current_rom;
	}
	
	// try to find a good rom
	do {
		runAddr = check_image(romconf->roms[romToBoot]);
		if (runAddr == 0) {
			ets_printf("Rom %d is bad.\r\n", romToBoot);
			if (gpio_boot) {
				// don't switch to backup for gpio-selected rom
				ets_printf("GPIO boot failed.\r\n");
				return 0;
			} else {
				// for normal mode try each previous rom
				// until we find a good one or run out
				updateConfig = TRUE;
				romToBoot--;
				if (romToBoot < 0) romToBoot = romconf->count - 1;
				if (romToBoot == romconf->current_rom) {
					// tried them all and all are bad!
					ets_printf("No good rom available.\r\n");
					return 0;
				}
			}
		}
	} while (runAddr == 0);
	
	// re-write config, if required
	if (updateConfig) {
		romconf->current_rom = romToBoot;
		SPIEraseSector(BOOT_CONFIG_SECTOR);
		SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	}
	
	ets_printf("Booting rom %d.\r\n", romToBoot);
	// copy the loader to top of iram
	ets_memcpy((void*)_text_addr, _text_data, _text_len);
	// return address to load from
	return runAddr;

}
示例#10
0
// prevent this function being placed inline with main
// to keep main's stack size as small as possible
// don't mark as static or it'll be optimised out when
// using the assembler stub
uint32 NOINLINE find_image() {

	uint8 flag;
	uint32 runAddr;
	uint32 flashsize;
	int32 romToBoot;
	uint8 gpio_boot = FALSE;
	uint8 updateConfig = TRUE;
	uint8 buffer[SECTOR_SIZE];

	rboot_config *romconf = (rboot_config*)buffer;
	rom_header *header = (rom_header*)buffer;

	// delay to slow boot (help see messages when debugging)
	//ets_delay_us(2000000);

	ets_printf("\r\nrBoot v1.2.1 - [email protected]\r\n");

	// read rom header
	SPIRead(0, header, sizeof(rom_header));

	// print and get flash size
	ets_printf("Flash Size:   ");
	flag = header->flags2 >> 4;
	if (flag == 0) {
		ets_printf("4 Mbit\r\n");
		flashsize = 0x80000;
	} else if (flag == 1) {
		ets_printf("2 Mbit\r\n");
		flashsize = 0x40000;
	} else if (flag == 2) {
		ets_printf("8 Mbit\r\n");
		flashsize = 0x100000;
	} else if (flag == 3) {
		ets_printf("16 Mbit\r\n");
#ifdef BOOT_BIG_FLASH
		flashsize = 0x200000;
#else
		flashsize = 0x100000; // limit to 8Mbit
#endif
	} else if (flag == 4) {
		ets_printf("32 Mbit\r\n");
#ifdef BOOT_BIG_FLASH
		flashsize = 0x400000;
#else
		flashsize = 0x100000; // limit to 8Mbit
#endif
	} else {
		ets_printf("unknown\r\n");
		// assume at least 4mbit
		flashsize = 0x80000;
	}

	// print spi mode
	ets_printf("Flash Mode:   ");
	if (header->flags1 == 0) {
		ets_printf("QIO\r\n");
	} else if (header->flags1 == 1) {
		ets_printf("QOUT\r\n");
	} else if (header->flags1 == 2) {
		ets_printf("DIO\r\n");
	} else if (header->flags1 == 3) {
		ets_printf("DOUT\r\n");
	} else {
		ets_printf("unknown\r\n");
	}

	// print spi speed
	ets_printf("Flash Speed:  ");
	flag = header->flags2 & 0x0f;
	if (flag == 0) ets_printf("40 MHz\r\n");
	else if (flag == 1) ets_printf("26.7 MHz\r\n");
	else if (flag == 2) ets_printf("20 MHz\r\n");
	else if (flag == 0x0f) ets_printf("80 MHz\r\n");
	else ets_printf("unknown\r\n");

	// print enabled options
#ifdef BOOT_BIG_FLASH
	ets_printf("rBoot Option: Big flash\r\n");
#endif
#ifdef BOOT_CONFIG_CHKSUM
	ets_printf("rBoot Option: Config chksum\r\n");
#endif
#ifdef BOOT_IROM_CHKSUM
	ets_printf("rBoot Option: irom chksum\r\n");
#endif

	ets_printf("\r\n");

	// read boot config
	SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	// fresh install or old version?
	if (romconf->magic != BOOT_CONFIG_MAGIC || romconf->version != BOOT_CONFIG_VERSION
#ifdef BOOT_CONFIG_CHKSUM
		|| romconf->chksum != calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum)
#endif
		) {
		/* Modified by Cesanta */
		ets_printf("Writing default boot config.\r\n");
		ets_memset(romconf, 0x00, sizeof(rboot_config));
		romconf->magic = BOOT_CONFIG_MAGIC;
		romconf->version = BOOT_CONFIG_VERSION;
		romconf->count = 2;
		romconf->mode = MODE_STANDARD;
		/* FWx_ADDR, FWx_FS_ADDR and FS_SIZE, FW_SIZE must be defined by -D */
		romconf->roms[0] = FW1_ADDR;
		romconf->roms[1] = FW2_ADDR;
		romconf->fs_addresses[0] = FW1_FS_ADDR;
		romconf->fs_addresses[1] = FW2_FS_ADDR;
		romconf->fs_sizes[0] = romconf->fs_sizes[1] = FS_SIZE;
		romconf->roms_sizes[0] = romconf->roms_sizes[1] = FW_SIZE;
#ifdef BOOT_CONFIG_CHKSUM
		romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum);
#endif
		// write new config sector
		SPIEraseSector(BOOT_CONFIG_SECTOR);
		SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	}

	// if gpio mode enabled check status of the gpio
	if ((romconf->mode & MODE_GPIO_ROM) && (get_gpio16() == 0)) {
		ets_printf("Booting GPIO-selected.\r\n");
		romToBoot = romconf->previous_rom;
		/*
		 * Modified by Cesanta
		 * Make FD current
		 */
		updateConfig = TRUE;
		romconf->fw_updated = 0;
		romconf->is_first_boot = 0;
		gpio_boot = TRUE;
	} else if (romconf->current_rom >= romconf->count) {
		// if invalid rom selected try rom 0
		ets_printf("Invalid rom selected, defaulting.\r\n");
		romToBoot = 0;
		romconf->current_rom = 0;
		romconf->fw_updated = 0;
		romconf->is_first_boot = 0;
		updateConfig = TRUE;
	} else {
		/* Modified by Cesanta */
		if (romconf->is_first_boot != 0) {
				ets_printf("First boot, attempt %d\n", romconf->boot_attempts);
			/* boot is unconfirmed */
			if (romconf->boot_attempts == 0) {
				/* haven't try to load yes */
				ets_printf("Boot is unconfirmed\r\n");
				romconf->boot_attempts++;
			} else {
				ets_printf("Boot failed, fallback to fw #%d\r\n",
											romconf->previous_rom);
				romconf->current_rom = romconf->previous_rom;
				/* clear fw update flag, to avoid post-update acttions */
				romconf->fw_updated = 0;
				romconf->boot_attempts = 0;
			}

			updateConfig = TRUE;
		}
		/* End of Cesanta modifications */
		// try rom selected in the config
		romToBoot = romconf->current_rom;
	}

	// try to find a good rom
	do {
		runAddr = check_image(romconf->roms[romToBoot]);
		if (runAddr == 0) {
			ets_printf("Rom %d is bad.\r\n", romToBoot);
			if (gpio_boot) {
				// don't switch to backup for gpio-selected rom
				ets_printf("GPIO boot failed.\r\n");
				return 0;
			} else {
				// for normal mode try each previous rom
				// until we find a good one or run out
				updateConfig = TRUE;
				romToBoot--;
				if (romToBoot < 0) romToBoot = romconf->count - 1;
				if (romToBoot == romconf->current_rom) {
					// tried them all and all are bad!
					ets_printf("No good rom available.\r\n");
					return 0;
				}
			}
		}
	} while (runAddr == 0);

	// re-write config, if required
	if (updateConfig) {
		romconf->current_rom = romToBoot;
#ifdef BOOT_CONFIG_CHKSUM
		romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum);
#endif
		SPIEraseSector(BOOT_CONFIG_SECTOR);
		SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	}

	ets_printf("Booting rom %d.\r\n", romToBoot);
	// copy the loader to top of iram
	ets_memcpy((void*)_text_addr, _text_data, _text_len);
	// return address to load from
	return runAddr;

}
示例#11
0
//=============================================================================
// call_user_start
//-----------------------------------------------------------------------------
void call_user_start(void)
{
	struct SPIFlashHead sfh; // заголовок flash
	struct StoreWifiHdr wifihdr; // заголовок из последнего сектора flash с индексом на сохранение последней конфигурации WiFi
    struct BootConfig bootcfg;	// начало блока сохранения последней конфигурации WiFi, часть с boot параметрами

	ets_printf("\n2nd boot version : 1.2\n");
	SPIRead(0, &sfh, sizeof(sfh));
	ets_printf("  SPI Speed      : ");
    switch (sfh.hsz.spi_freg)
	{
	    case SPEED_40MHZ:
	    	ets_printf("40MHz\n");
	    	break;
	    case SPEED_26MHZ:
	    	ets_printf("26.7MHz\n");
	    	break;
	    case SPEED_20MHZ:
	    	ets_printf("20MHz\n");
	    	break;
	    case SPEED_80MHZ:
	    	ets_printf("80MHz\n");
	    	break;
	}
	ets_printf("  SPI Mode       : ");
	switch (sfh.spi_interface)
    {
	    case MODE_QIO:
	    	ets_printf("QIO\n");
	    	break;
	    case MODE_QOUT:
	    	ets_printf("QOUT\n");
	    	break;
	    case MODE_DIO:
	    	ets_printf("DIO\n");
	    	break;
	    case MODE_DOUT:
	    	ets_printf("DOUT\n");
	    	break;
    }
	ets_printf("  SPI Flash Size : ");
	uint32 sector;
	switch (sfh.hsz.flash_size)
	{
		case SIZE_4MBIT:
			ets_printf("4Mbit\n");
			sector = 128-4;
			break;
	    case SIZE_2MBIT:
	    	ets_printf("2Mbit\n");
	    	sector = 64-4;
	    	break;
	    case SIZE_8MBIT:
	    	ets_printf("8Mbit\n");
	    	sector = 256-4;
	    	break;
	    case SIZE_16MBIT:
	    	ets_printf("16Mbit\n");
	    	sector = 512-4;
	    	break;
	    case SIZE_32MBIT:
	    	ets_printf("32Mbit\n");
	    	sector = 1024-4;
	    	break;
	    default:
			ets_printf("4Mbit\n");
			sector = 128-4;
			break;
	}
	uint32 addr = sector * FSECTOR_SIZE;
	SPIRead(addr + 3 * FSECTOR_SIZE, &wifihdr.bank, sizeof(wifihdr));
	if(wifihdr.bank == 0) {
		SPIRead(addr + FSECTOR_SIZE, &bootcfg, sizeof(bootcfg));
	}
	else {
		SPIRead(addr + 2 * FSECTOR_SIZE, &bootcfg, sizeof(bootcfg));
	}
	if(bootcfg.boot_version == 0xff) {
		bootcfg.boot_number = 0;
	}
	if(bootcfg.boot_version != 2) {
			bootcfg.boot_version = 2;
			if(wifihdr.bank == 0) wifihdr.bank = 1;
			else wifihdr.bank = 0;
			SPIEraseSector(sector+wifihdr.bank+1);
			SPIWrite((sector+wifihdr.bank+1) * FSECTOR_SIZE, &bootcfg, sizeof(bootcfg));
			SPIEraseSector(sector+3);
			SPIWrite(addr + 3 * FSECTOR_SIZE, &wifihdr.bank, sizeof(wifihdr));
	}
	ets_memcpy((void *)0x4010800, &code_blk, size_code_blk); // загрузчик не прикреплен!
	ets_printf("jump to run user");
	switch(bootcfg.boot_number & 0x0f)
	{
		case 0:
			ets_printf("1\n\n");
			uint32 seg_size = get_seg_size(FSECTOR_SIZE);
			if(seg_size == 0xffffffff) return;
			if(seg_size == 0) {
				0x4010800C(FSECTOR_SIZE);
			} else {
				0x4010800C(seg_size + 0x1010);
			}
			break;
		case 1:
			ets_printf("2\n\n");
			if(sector == 512 - 4 || sector == 1024 - 4) sector = 256 - 4;
			get_seg_size(((sector + 4)>>1)*FSECTOR_SIZE + FSECTOR_SIZE);
			if(seg_size == 0xffffffff) return;
			if(seg_size == 0) {
				0x4010800C(FSECTOR_SIZE);
			} else {
				0x4010800C(seg_size + 0x1010);
			}
			break;
		default:
			ets_printf("error user bin flag, flag = %x\n", bootcfg.boot_number & 0x0f);
	}
}
示例#12
0
文件: rboot.c 项目: stevegt/dboot
/** Checks the boot config sector to see if there's a new image to write and if so, erases old and copies in new
 * @note Must be NOINLINE and not static to call from ASM without generating a stack which will be left in memory
 */
void NOINLINE copyNewImage(void)
{
  BootloaderConfig config;
  SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, &config, sizeof(BootloaderConfig));
  if (config.header != BOOT_CONFIG_HEADER)
  {
    ets_printf("No boot config header, %08x != %08x, skipping\r\n", config.header, BOOT_CONFIG_HEADER);
    return;
  }
  else if (calc_chksum((uint8*)&config, (uint8*)&config.chksum) != config.chksum)
  {
    ets_printf("ERROR: boot config has bad checksum, %02x, expecting %02x\r\n",
               config.chksum, calc_chksum((uint8*)&config, (uint8*)&config.chksum));
    return;
  }
  else if (config.newImageStart == 0 || config.newImageSize == 0)
  {
    ets_printf("No new firmware, continuing\r\n");
    return;
  }
  else
  {
    uint32 buffer[SECTOR_SIZE/4]; // Buffer to copy from one sector to another
    uint32 sector;
    SpiFlashOpResult rslt;
    
    ets_printf("Found new image: %x[%d]\r\n", config.newImageStart, config.newImageSize);
    
    ets_printf("\tErasing old firmware\r\n");
    for (sector = FIRMWARE_START_SECTOR; sector < FIRMWARE_START_SECTOR + config.newImageSize; sector++)
    {
      rslt = SPIEraseSector(sector);
      if (rslt != SPI_FLASH_RESULT_OK)
      {
        ets_printf("\tError erasing sector %x: %d\r\n", sector, rslt);
        sector--; // Try this sector again
      }
      else
      {
        ets_printf("_");
      }
    }
    
    ets_printf("\tCopying in new firmware\r\n");
    for (sector = 0; sector < config.newImageSize; sector++)
    {
      rslt = SPIRead((sector + config.newImageStart)*SECTOR_SIZE + IMAGE_READ_OFFSET, buffer, SECTOR_SIZE);
      if (rslt != SPI_FLASH_RESULT_OK)
      {
        ets_printf("\tError reading sector %x: %d\r\n", sector + config.newImageStart, rslt);
        sector--; // Retry the same sector
      }
      else
      {
        rslt = SPIWrite((sector + FIRMWARE_START_SECTOR)*SECTOR_SIZE, buffer, SECTOR_SIZE);
        if (rslt != SPI_FLASH_RESULT_OK)
        {
          ets_printf("\tError writing sector %x: %d\r\n", sector + FIRMWARE_START_SECTOR, rslt);
          sector--; // Retry the same sector
        }
        else
        {
          ets_printf(".");
        }
      }
    }
    ets_printf("Done copying new image, %d sectors\r\n", sector);
  }
}