Skip to content

Commit 51daecc

Browse files
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.
1 parent 0deb874 commit 51daecc

File tree

3 files changed

+38
-70
lines changed

3 files changed

+38
-70
lines changed

bootloaders/eboot/eboot.c

+30-68
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include <string.h>
1313
#include "flash.h"
1414
#include "eboot_command.h"
15-
#include "spi_vendors.h"
1615
#include <uzlib.h>
1716

1817
extern unsigned char _gzip_dict;
@@ -115,10 +114,12 @@ int uzlib_flash_read_cb(struct uzlib_uncomp *m)
115114
}
116115

117116
unsigned char gzip_dict[32768];
117+
uint8_t buffer2[FLASH_SECTOR_SIZE]; // no room for this on the stack
118118

119119
int copy_raw(const uint32_t src_addr,
120120
const uint32_t dst_addr,
121-
const uint32_t size)
121+
const uint32_t size,
122+
const bool verify)
122123
{
123124
// require regions to be aligned
124125
if ((src_addr & 0xfff) != 0 ||
@@ -158,8 +159,10 @@ int copy_raw(const uint32_t src_addr,
158159
gzip = true;
159160
}
160161
while (left > 0) {
161-
if (SPIEraseSector(daddr/buffer_size)) {
162-
return 2;
162+
if (!verify) {
163+
if (SPIEraseSector(daddr/buffer_size)) {
164+
return 2;
165+
}
163166
}
164167
if (!gzip) {
165168
if (SPIRead(saddr, buffer, buffer_size)) {
@@ -179,8 +182,17 @@ int copy_raw(const uint32_t src_addr,
179182
buffer[i] = 0xff;
180183
}
181184
}
182-
if (SPIWrite(daddr, buffer, buffer_size)) {
183-
return 4;
185+
if (verify) {
186+
if (SPIRead(daddr, buffer2, buffer_size)) {
187+
return 4;
188+
}
189+
if (memcmp(buffer, buffer2, buffer_size)) {
190+
return 9;
191+
}
192+
} else {
193+
if (SPIWrite(daddr, buffer, buffer_size)) {
194+
return 4;
195+
}
184196
}
185197
saddr += buffer_size;
186198
daddr += buffer_size;
@@ -190,29 +202,6 @@ int copy_raw(const uint32_t src_addr,
190202
return 0;
191203
}
192204

193-
//#define XMC_SUPPORT
194-
#ifdef XMC_SUPPORT
195-
// Define a few SPI0 registers we need access to
196-
#define ESP8266_REG(addr) *((volatile uint32_t *)(0x60000000+(addr)))
197-
#define SPI0CMD ESP8266_REG(0x200)
198-
#define SPI0CLK ESP8266_REG(0x218)
199-
#define SPI0C ESP8266_REG(0x208)
200-
#define SPI0W0 ESP8266_REG(0x240)
201-
202-
#define SPICMDRDID (1 << 28)
203-
204-
/* spi_flash_get_id()
205-
Returns the flash chip ID - same as the SDK function.
206-
We need our own version as the SDK isn't available here.
207-
*/
208-
uint32_t __attribute__((noinline)) spi_flash_get_id() {
209-
SPI0W0=0;
210-
SPI0CMD=SPICMDRDID;
211-
while (SPI0CMD) {}
212-
return SPI0W0;
213-
}
214-
#endif // XMC_SUPPORT
215-
216205
int main()
217206
{
218207
int res = 9;
@@ -235,47 +224,20 @@ int main()
235224
if (cmd.action == ACTION_COPY_RAW) {
236225
ets_putc('c'); ets_putc('p'); ets_putc(':');
237226

238-
#ifdef XMC_SUPPORT
239-
// save the flash access speed registers
240-
uint32_t spi0clk = SPI0CLK;
241-
uint32_t spi0c = SPI0C;
242-
243-
uint32_t vendor = spi_flash_get_id() & 0x000000ff;
244-
if (vendor == SPI_FLASH_VENDOR_XMC) {
245-
uint32_t flashinfo=0;
246-
if (SPIRead(0, &flashinfo, 4)) {
247-
// failed to read the configured flash speed.
248-
// Do not change anything,
249-
} else {
250-
// select an appropriate flash speed
251-
// Register values are those used by ROM
252-
switch ((flashinfo >> 24) & 0x0f) {
253-
case 0x0: // 40MHz, slow to 20
254-
case 0x1: // 26MHz, slow to 20
255-
SPI0CLK = 0x00003043;
256-
SPI0C = 0x00EAA313;
257-
break;
258-
case 0x2: // 20MHz, no change
259-
break;
260-
case 0xf: // 80MHz, slow to 26
261-
SPI0CLK = 0x00002002;
262-
SPI0C = 0x00EAA202;
263-
break;
264-
default:
265-
break;
266-
}
267-
}
268-
}
269-
#endif // XMC_SUPPORT
270227
ets_wdt_disable();
271-
res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]);
228+
res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2], false);
272229
ets_wdt_enable();
273-
274-
#ifdef XMC_SUPPORT
275-
// restore the saved flash access speed registers
276-
SPI0CLK = spi0clk;
277-
SPI0C = spi0c;
278-
#endif
230+
231+
ets_putc('0'+res); ets_putc('\n');
232+
233+
// Verify the copy
234+
ets_putc('c'); ets_putc('m'); ets_putc('p'); ets_putc(':');
235+
if (res == 0) {
236+
ets_wdt_disable();
237+
res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2], true);
238+
ets_wdt_enable();
239+
}
240+
279241
ets_putc('0'+res); ets_putc('\n');
280242
if (res == 0) {
281243
cmd.action = ACTION_LOAD_APP;

bootloaders/eboot/eboot.elf

1020 Bytes
Binary file not shown.

cores/esp8266/core_esp8266_spi_utils.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ static SpiOpResult PRECACHE_ATTR
5252
_SPICommand(volatile uint32_t spiIfNum,
5353
uint32_t spic,uint32_t spiu,uint32_t spiu1,uint32_t spiu2,
5454
uint32_t *data,uint32_t writeWords,uint32_t readWords)
55-
{
55+
{
5656
if (spiIfNum>1)
5757
return SPI_RESULT_ERR;
5858

@@ -69,8 +69,11 @@ _SPICommand(volatile uint32_t spiIfNum,
6969
volatile SpiFlashChip *fchip=flashchip;
7070
volatile uint32_t spicmdusr=SPICMDUSR;
7171

72+
uint32_t saved_ps=0;
73+
7274
if (!spiIfNum) {
73-
// Only need to precache when using SPI0
75+
// Only need to disable interrupts and precache when using SPI0
76+
saved_ps = xt_rsil(15);
7477
PRECACHE_START();
7578
Wait_SPI_Idlep((SpiFlashChip *)fchip);
7679
}
@@ -116,6 +119,9 @@ _SPICommand(volatile uint32_t spiIfNum,
116119
SPIREG(SPI0C) = oldSPI0C;
117120

118121
PRECACHE_END();
122+
if (!spiIfNum) {
123+
xt_wsr_ps(saved_ps);
124+
}
119125
return (timeout>0 ? SPI_RESULT_OK : SPI_RESULT_TIMEOUT);
120126
}
121127

0 commit comments

Comments
 (0)