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 "flash.h"
|
||||
#include "eboot_command.h"
|
||||
#include "spi_vendors.h"
|
||||
#include <uzlib.h>
|
||||
|
||||
extern unsigned char _gzip_dict;
|
||||
@ -115,10 +114,12 @@ int uzlib_flash_read_cb(struct uzlib_uncomp *m)
|
||||
}
|
||||
|
||||
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,
|
||||
const uint32_t dst_addr,
|
||||
const uint32_t size)
|
||||
const uint32_t size,
|
||||
const bool verify)
|
||||
{
|
||||
// require regions to be aligned
|
||||
if ((src_addr & 0xfff) != 0 ||
|
||||
@ -158,8 +159,10 @@ int copy_raw(const uint32_t src_addr,
|
||||
gzip = true;
|
||||
}
|
||||
while (left > 0) {
|
||||
if (SPIEraseSector(daddr/buffer_size)) {
|
||||
return 2;
|
||||
if (!verify) {
|
||||
if (SPIEraseSector(daddr/buffer_size)) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (!gzip) {
|
||||
if (SPIRead(saddr, buffer, buffer_size)) {
|
||||
@ -179,8 +182,17 @@ int copy_raw(const uint32_t src_addr,
|
||||
buffer[i] = 0xff;
|
||||
}
|
||||
}
|
||||
if (SPIWrite(daddr, buffer, buffer_size)) {
|
||||
return 4;
|
||||
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)) {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
saddr += buffer_size;
|
||||
daddr += buffer_size;
|
||||
@ -190,29 +202,6 @@ int copy_raw(const uint32_t src_addr,
|
||||
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 res = 9;
|
||||
@ -235,47 +224,20 @@ int main()
|
||||
if (cmd.action == ACTION_COPY_RAW) {
|
||||
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();
|
||||
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();
|
||||
|
||||
#ifdef XMC_SUPPORT
|
||||
// restore the saved flash access speed registers
|
||||
SPI0CLK = spi0clk;
|
||||
SPI0C = spi0c;
|
||||
#endif
|
||||
|
||||
ets_putc('0'+res); ets_putc('\n');
|
||||
|
||||
// Verify the copy
|
||||
ets_putc('c'); ets_putc('m'); ets_putc('p'); ets_putc(':');
|
||||
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');
|
||||
if (res == 0) {
|
||||
cmd.action = ACTION_LOAD_APP;
|
||||
|
Binary file not shown.
@ -52,7 +52,7 @@ static SpiOpResult PRECACHE_ATTR
|
||||
_SPICommand(volatile uint32_t spiIfNum,
|
||||
uint32_t spic,uint32_t spiu,uint32_t spiu1,uint32_t spiu2,
|
||||
uint32_t *data,uint32_t writeWords,uint32_t readWords)
|
||||
{
|
||||
{
|
||||
if (spiIfNum>1)
|
||||
return SPI_RESULT_ERR;
|
||||
|
||||
@ -69,8 +69,11 @@ _SPICommand(volatile uint32_t spiIfNum,
|
||||
volatile SpiFlashChip *fchip=flashchip;
|
||||
volatile uint32_t spicmdusr=SPICMDUSR;
|
||||
|
||||
uint32_t saved_ps=0;
|
||||
|
||||
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();
|
||||
Wait_SPI_Idlep((SpiFlashChip *)fchip);
|
||||
}
|
||||
@ -116,6 +119,9 @@ _SPICommand(volatile uint32_t spiIfNum,
|
||||
SPIREG(SPI0C) = oldSPI0C;
|
||||
|
||||
PRECACHE_END();
|
||||
if (!spiIfNum) {
|
||||
xt_wsr_ps(saved_ps);
|
||||
}
|
||||
return (timeout>0 ? SPI_RESULT_OK : SPI_RESULT_TIMEOUT);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user