1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Xmc flash 2 (#7317)

* Remove unnecessary XMC support from eboot

eboot is always run with the flash access speed set to 20MHz, so
there is no need for special treatment of XMC chips.

* After eboot copies the new firmware into place, verify the copy.

If the data written to flash is as expected, the line cmp:0 will be displayed
after the usual @cp:0 from eboot.

* Disable interrupts during the precached part of _SPICommand()

For some reason this was an issue during the reboot after an OTA update.
This commit is contained in:
Mike Nix 2020-05-27 08:04:49 +08:00 committed by GitHub
parent 0deb87483e
commit 51daecc236
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 70 deletions

View File

@ -12,7 +12,6 @@
#include <string.h> #include <string.h>
#include "flash.h" #include "flash.h"
#include "eboot_command.h" #include "eboot_command.h"
#include "spi_vendors.h"
#include <uzlib.h> #include <uzlib.h>
extern unsigned char _gzip_dict; extern unsigned char _gzip_dict;
@ -115,10 +114,12 @@ int uzlib_flash_read_cb(struct uzlib_uncomp *m)
} }
unsigned char gzip_dict[32768]; unsigned char gzip_dict[32768];
uint8_t buffer2[FLASH_SECTOR_SIZE]; // no room for this on the stack
int copy_raw(const uint32_t src_addr, int copy_raw(const uint32_t src_addr,
const uint32_t dst_addr, const uint32_t dst_addr,
const uint32_t size) const uint32_t size,
const bool verify)
{ {
// require regions to be aligned // require regions to be aligned
if ((src_addr & 0xfff) != 0 || if ((src_addr & 0xfff) != 0 ||
@ -158,9 +159,11 @@ int copy_raw(const uint32_t src_addr,
gzip = true; gzip = true;
} }
while (left > 0) { while (left > 0) {
if (!verify) {
if (SPIEraseSector(daddr/buffer_size)) { if (SPIEraseSector(daddr/buffer_size)) {
return 2; return 2;
} }
}
if (!gzip) { if (!gzip) {
if (SPIRead(saddr, buffer, buffer_size)) { if (SPIRead(saddr, buffer, buffer_size)) {
return 3; return 3;
@ -179,9 +182,18 @@ int copy_raw(const uint32_t src_addr,
buffer[i] = 0xff; buffer[i] = 0xff;
} }
} }
if (verify) {
if (SPIRead(daddr, buffer2, buffer_size)) {
return 4;
}
if (memcmp(buffer, buffer2, buffer_size)) {
return 9;
}
} else {
if (SPIWrite(daddr, buffer, buffer_size)) { if (SPIWrite(daddr, buffer, buffer_size)) {
return 4; return 4;
} }
}
saddr += buffer_size; saddr += buffer_size;
daddr += buffer_size; daddr += buffer_size;
left -= buffer_size; left -= buffer_size;
@ -190,29 +202,6 @@ int copy_raw(const uint32_t src_addr,
return 0; return 0;
} }
//#define XMC_SUPPORT
#ifdef XMC_SUPPORT
// Define a few SPI0 registers we need access to
#define ESP8266_REG(addr) *((volatile uint32_t *)(0x60000000+(addr)))
#define SPI0CMD ESP8266_REG(0x200)
#define SPI0CLK ESP8266_REG(0x218)
#define SPI0C ESP8266_REG(0x208)
#define SPI0W0 ESP8266_REG(0x240)
#define SPICMDRDID (1 << 28)
/* spi_flash_get_id()
Returns the flash chip ID - same as the SDK function.
We need our own version as the SDK isn't available here.
*/
uint32_t __attribute__((noinline)) spi_flash_get_id() {
SPI0W0=0;
SPI0CMD=SPICMDRDID;
while (SPI0CMD) {}
return SPI0W0;
}
#endif // XMC_SUPPORT
int main() int main()
{ {
int res = 9; int res = 9;
@ -235,47 +224,20 @@ int main()
if (cmd.action == ACTION_COPY_RAW) { if (cmd.action == ACTION_COPY_RAW) {
ets_putc('c'); ets_putc('p'); ets_putc(':'); ets_putc('c'); ets_putc('p'); ets_putc(':');
#ifdef XMC_SUPPORT
// save the flash access speed registers
uint32_t spi0clk = SPI0CLK;
uint32_t spi0c = SPI0C;
uint32_t vendor = spi_flash_get_id() & 0x000000ff;
if (vendor == SPI_FLASH_VENDOR_XMC) {
uint32_t flashinfo=0;
if (SPIRead(0, &flashinfo, 4)) {
// failed to read the configured flash speed.
// Do not change anything,
} else {
// select an appropriate flash speed
// Register values are those used by ROM
switch ((flashinfo >> 24) & 0x0f) {
case 0x0: // 40MHz, slow to 20
case 0x1: // 26MHz, slow to 20
SPI0CLK = 0x00003043;
SPI0C = 0x00EAA313;
break;
case 0x2: // 20MHz, no change
break;
case 0xf: // 80MHz, slow to 26
SPI0CLK = 0x00002002;
SPI0C = 0x00EAA202;
break;
default:
break;
}
}
}
#endif // XMC_SUPPORT
ets_wdt_disable(); ets_wdt_disable();
res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]); res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2], false);
ets_wdt_enable(); ets_wdt_enable();
#ifdef XMC_SUPPORT ets_putc('0'+res); ets_putc('\n');
// restore the saved flash access speed registers
SPI0CLK = spi0clk; // Verify the copy
SPI0C = spi0c; ets_putc('c'); ets_putc('m'); ets_putc('p'); ets_putc(':');
#endif if (res == 0) {
ets_wdt_disable();
res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2], true);
ets_wdt_enable();
}
ets_putc('0'+res); ets_putc('\n'); ets_putc('0'+res); ets_putc('\n');
if (res == 0) { if (res == 0) {
cmd.action = ACTION_LOAD_APP; cmd.action = ACTION_LOAD_APP;

Binary file not shown.

View File

@ -69,8 +69,11 @@ _SPICommand(volatile uint32_t spiIfNum,
volatile SpiFlashChip *fchip=flashchip; volatile SpiFlashChip *fchip=flashchip;
volatile uint32_t spicmdusr=SPICMDUSR; volatile uint32_t spicmdusr=SPICMDUSR;
uint32_t saved_ps=0;
if (!spiIfNum) { if (!spiIfNum) {
// Only need to precache when using SPI0 // Only need to disable interrupts and precache when using SPI0
saved_ps = xt_rsil(15);
PRECACHE_START(); PRECACHE_START();
Wait_SPI_Idlep((SpiFlashChip *)fchip); Wait_SPI_Idlep((SpiFlashChip *)fchip);
} }
@ -116,6 +119,9 @@ _SPICommand(volatile uint32_t spiIfNum,
SPIREG(SPI0C) = oldSPI0C; SPIREG(SPI0C) = oldSPI0C;
PRECACHE_END(); PRECACHE_END();
if (!spiIfNum) {
xt_wsr_ps(saved_ps);
}
return (timeout>0 ? SPI_RESULT_OK : SPI_RESULT_TIMEOUT); return (timeout>0 ? SPI_RESULT_OK : SPI_RESULT_TIMEOUT);
} }