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:
parent
0deb87483e
commit
51daecc236
@ -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.
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user