Skip to content

Commit 9b41d9a

Browse files
ChocolateFrogsNutsdevyteearlephilhower
authored
XMC flash support - WIP (#6725)
* Move the spi vendor list from Esp.h to its own header in eboot. * Fix ifdef issue with spi_vendors.h * Add initFlashQuirks() for any chip specific flash initialization. Called from user_init(). * namespace experimental for initFlashQuirks() * Slow down flash access during eboot firmware copy Part 1 - still some work to do * Slow down flash access during eboot firmware copy on XMC chips Part 2 - Identify the chip type. Note: there may still be issues with the access speed change. This is very much experimental. * Commit eboot.elf Co-authored-by: Develo <[email protected]> Co-authored-by: Earle F. Philhower, III <[email protected]>
1 parent 2de9242 commit 9b41d9a

10 files changed

+346
-37
lines changed

bootloaders/eboot/eboot.c

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

1718
extern unsigned char _gzip_dict;
@@ -189,6 +190,28 @@ int copy_raw(const uint32_t src_addr,
189190
return 0;
190191
}
191192

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
192215

193216
int main()
194217
{
@@ -211,9 +234,48 @@ int main()
211234

212235
if (cmd.action == ACTION_COPY_RAW) {
213236
ets_putc('c'); ets_putc('p'); ets_putc(':');
237+
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
214270
ets_wdt_disable();
215271
res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]);
216272
ets_wdt_enable();
273+
274+
#ifdef XMC_SUPPORT
275+
// restore the saved flash access speed registers
276+
SPI0CLK = spi0clk;
277+
SPI0C = spi0c;
278+
#endif
217279
ets_putc('0'+res); ets_putc('\n');
218280
if (res == 0) {
219281
cmd.action = ACTION_LOAD_APP;

bootloaders/eboot/eboot.elf

1.64 KB
Binary file not shown.

bootloaders/eboot/spi_vendors.h

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
spi_vendors.h - Vendor IDs for SPI chips
3+
Copyright (c) 2019 Mike Nix. All rights reserved.
4+
This file is part of the esp8266 core for Arduino environment.
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#ifndef __SPI_VENDORS_H__
22+
#define __SPI_VENDORS_H__
23+
24+
// Vendor IDs taken from Flashrom project
25+
// https://review.coreboot.org/cgit/flashrom.git/tree/flashchips.h?h=1.0.x
26+
// Moved here from ../../cores/esp8266/Esp.h
27+
typedef enum {
28+
SPI_FLASH_VENDOR_ALLIANCE = 0x52, /* Alliance Semiconductor */
29+
SPI_FLASH_VENDOR_AMD = 0x01, /* AMD */
30+
SPI_FLASH_VENDOR_AMIC = 0x37, /* AMIC */
31+
SPI_FLASH_VENDOR_ATMEL = 0x1F, /* Atmel (now used by Adesto) */
32+
SPI_FLASH_VENDOR_BRIGHT = 0xAD, /* Bright Microelectronics */
33+
SPI_FLASH_VENDOR_CATALYST = 0x31, /* Catalyst */
34+
SPI_FLASH_VENDOR_EON = 0x1C, /* EON Silicon Devices, missing 0x7F prefix */
35+
SPI_FLASH_VENDOR_ESMT = 0x8C, /* Elite Semiconductor Memory Technology (ESMT) / EFST Elite Flash Storage */
36+
SPI_FLASH_VENDOR_EXCEL = 0x4A, /* ESI, missing 0x7F prefix */
37+
SPI_FLASH_VENDOR_FIDELIX = 0xF8, /* Fidelix */
38+
SPI_FLASH_VENDOR_FUJITSU = 0x04, /* Fujitsu */
39+
SPI_FLASH_VENDOR_GIGADEVICE = 0xC8, /* GigaDevice */
40+
SPI_FLASH_VENDOR_HYUNDAI = 0xAD, /* Hyundai */
41+
SPI_FLASH_VENDOR_INTEL = 0x89, /* Intel */
42+
SPI_FLASH_VENDOR_ISSI = 0xD5, /* ISSI Integrated Silicon Solutions, see also PMC. */
43+
SPI_FLASH_VENDOR_MACRONIX = 0xC2, /* Macronix (MX) */
44+
SPI_FLASH_VENDOR_NANTRONICS = 0xD5, /* Nantronics, missing prefix */
45+
SPI_FLASH_VENDOR_PMC = 0x9D, /* PMC, missing 0x7F prefix */
46+
SPI_FLASH_VENDOR_PUYA = 0x85, /* Puya semiconductor (shanghai) co. ltd */
47+
SPI_FLASH_VENDOR_SANYO = 0x62, /* Sanyo */
48+
SPI_FLASH_VENDOR_SHARP = 0xB0, /* Sharp */
49+
SPI_FLASH_VENDOR_SPANSION = 0x01, /* Spansion, same ID as AMD */
50+
SPI_FLASH_VENDOR_SST = 0xBF, /* SST */
51+
SPI_FLASH_VENDOR_ST = 0x20, /* ST / SGS/Thomson / Numonyx (later acquired by Micron) */
52+
SPI_FLASH_VENDOR_SYNCMOS_MVC = 0x40, /* SyncMOS (SM) and Mosel Vitelic Corporation (MVC) */
53+
SPI_FLASH_VENDOR_TENX = 0x5E, /* Tenx Technologies */
54+
SPI_FLASH_VENDOR_TI = 0x97, /* Texas Instruments */
55+
SPI_FLASH_VENDOR_TI_OLD = 0x01, /* TI chips from last century */
56+
SPI_FLASH_VENDOR_WINBOND = 0xDA, /* Winbond */
57+
SPI_FLASH_VENDOR_WINBOND_NEX = 0xEF, /* Winbond (ex Nexcom) serial flashes */
58+
SPI_FLASH_VENDOR_XMC = 0x20, /* Wuhan Xinxin Semiconductor Manufacturing Corp */
59+
60+
SPI_FLASH_VENDOR_UNKNOWN = 0xFF
61+
} SPI_FLASH_VENDOR_t;
62+
63+
#endif // __SPI_VENDORS_H__

cores/esp8266/Esp.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ uint32_t EspClass::getFlashChipSizeByChipId(void) {
404404
return (64_kB);
405405

406406
// Winbond
407+
case 0x1840EF: // W25Q128
408+
return (16_MB);
407409
case 0x1640EF: // W25Q32
408410
return (4_MB);
409411
case 0x1540EF: // W25Q16
@@ -423,6 +425,10 @@ uint32_t EspClass::getFlashChipSizeByChipId(void) {
423425
case 0x1340E0: // BG25Q40
424426
return (512_kB);
425427

428+
// XMC - Wuhan Xinxin Semiconductor Manufacturing Corp
429+
case 0x164020: // XM25QH32B
430+
return (4_MB);
431+
426432
default:
427433
return 0;
428434
}

cores/esp8266/Esp.h

+1-37
Original file line numberDiff line numberDiff line change
@@ -22,43 +22,7 @@
2222
#define ESP_H
2323

2424
#include <Arduino.h>
25-
26-
// Vendor IDs taken from Flashrom project
27-
// https://review.coreboot.org/cgit/flashrom.git/tree/flashchips.h?h=1.0.x
28-
typedef enum {
29-
SPI_FLASH_VENDOR_ALLIANCE = 0x52, /* Alliance Semiconductor */
30-
SPI_FLASH_VENDOR_AMD = 0x01, /* AMD */
31-
SPI_FLASH_VENDOR_AMIC = 0x37, /* AMIC */
32-
SPI_FLASH_VENDOR_ATMEL = 0x1F, /* Atmel (now used by Adesto) */
33-
SPI_FLASH_VENDOR_BRIGHT = 0xAD, /* Bright Microelectronics */
34-
SPI_FLASH_VENDOR_CATALYST = 0x31, /* Catalyst */
35-
SPI_FLASH_VENDOR_EON = 0x1C, /* EON Silicon Devices, missing 0x7F prefix */
36-
SPI_FLASH_VENDOR_ESMT = 0x8C, /* Elite Semiconductor Memory Technology (ESMT) / EFST Elite Flash Storage */
37-
SPI_FLASH_VENDOR_EXCEL = 0x4A, /* ESI, missing 0x7F prefix */
38-
SPI_FLASH_VENDOR_FIDELIX = 0xF8, /* Fidelix */
39-
SPI_FLASH_VENDOR_FUJITSU = 0x04, /* Fujitsu */
40-
SPI_FLASH_VENDOR_GIGADEVICE = 0xC8, /* GigaDevice */
41-
SPI_FLASH_VENDOR_HYUNDAI = 0xAD, /* Hyundai */
42-
SPI_FLASH_VENDOR_INTEL = 0x89, /* Intel */
43-
SPI_FLASH_VENDOR_ISSI = 0xD5, /* ISSI Integrated Silicon Solutions, see also PMC. */
44-
SPI_FLASH_VENDOR_MACRONIX = 0xC2, /* Macronix (MX) */
45-
SPI_FLASH_VENDOR_NANTRONICS = 0xD5, /* Nantronics, missing prefix */
46-
SPI_FLASH_VENDOR_PMC = 0x9D, /* PMC, missing 0x7F prefix */
47-
SPI_FLASH_VENDOR_PUYA = 0x85, /* Puya semiconductor (shanghai) co. ltd */
48-
SPI_FLASH_VENDOR_SANYO = 0x62, /* Sanyo */
49-
SPI_FLASH_VENDOR_SHARP = 0xB0, /* Sharp */
50-
SPI_FLASH_VENDOR_SPANSION = 0x01, /* Spansion, same ID as AMD */
51-
SPI_FLASH_VENDOR_SST = 0xBF, /* SST */
52-
SPI_FLASH_VENDOR_ST = 0x20, /* ST / SGS/Thomson / Numonyx (later acquired by Micron) */
53-
SPI_FLASH_VENDOR_SYNCMOS_MVC = 0x40, /* SyncMOS (SM) and Mosel Vitelic Corporation (MVC) */
54-
SPI_FLASH_VENDOR_TENX = 0x5E, /* Tenx Technologies */
55-
SPI_FLASH_VENDOR_TI = 0x97, /* Texas Instruments */
56-
SPI_FLASH_VENDOR_TI_OLD = 0x01, /* TI chips from last century */
57-
SPI_FLASH_VENDOR_WINBOND = 0xDA, /* Winbond */
58-
SPI_FLASH_VENDOR_WINBOND_NEX = 0xEF, /* Winbond (ex Nexcom) serial flashes */
59-
60-
SPI_FLASH_VENDOR_UNKNOWN = 0xFF
61-
} SPI_FLASH_VENDOR_t;
25+
#include "spi_vendors.h"
6226

6327
/**
6428
* AVR macros for WDT managment
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
flash_quirks.cpp - Chip specific flash init
3+
Copyright (c) 2019 Mike Nix. All rights reserved.
4+
This file is part of the esp8266 core for Arduino environment.
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#include <c_types.h>
22+
#include "spi_flash.h"
23+
24+
#include "spi_utils.h"
25+
#include "flash_quirks.h"
26+
27+
#ifdef __cplusplus
28+
extern "C" {
29+
#endif
30+
31+
namespace experimental {
32+
33+
static int get_flash_mhz() {
34+
// FIXME: copied from Esp.cpp - we really should define the magic values
35+
uint32_t data;
36+
uint8_t * bytes = (uint8_t *) &data;
37+
// read first 4 byte (magic byte + flash config)
38+
if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) {
39+
switch (bytes[3] & 0x0F) {
40+
case 0x0: // 40 MHz
41+
return 40;
42+
case 0x1: // 26 MHz
43+
return 26;
44+
case 0x2: // 20 MHz
45+
return 20;
46+
case 0xf: // 80 MHz
47+
return 80;
48+
default: // fail?
49+
return 0;
50+
}
51+
}
52+
return 0;
53+
}
54+
55+
/* initFlashQuirks()
56+
* Do any chip-specific initialization to improve performance and reliability.
57+
*/
58+
void initFlashQuirks() {
59+
using namespace experimental;
60+
uint32_t vendor = spi_flash_get_id() & 0x000000ff;
61+
62+
switch (vendor) {
63+
case SPI_FLASH_VENDOR_XMC:
64+
uint32_t SR3, newSR3;
65+
if (SPI0Command(SPI_FLASH_CMD_RSR3, &SR3, 0, 8)==SPI_RESULT_OK) { // read SR3
66+
newSR3=SR3;
67+
if (get_flash_mhz()>26) { // >26Mhz?
68+
// Set the output drive to 100%
69+
newSR3 &= ~(SPI_FLASH_SR3_XMC_DRV_MASK << SPI_FLASH_SR3_XMC_DRV_S);
70+
newSR3 |= (SPI_FLASH_SR3_XMC_DRV_100 << SPI_FLASH_SR3_XMC_DRV_S);
71+
}
72+
if (newSR3 != SR3) { // only write if changed
73+
if (SPI0Command(SPI_FLASH_CMD_WEVSR,NULL,0,0)==SPI_RESULT_OK) // write enable volatile SR
74+
SPI0Command(SPI_FLASH_CMD_WSR3,&newSR3,8,0); // write to SR3
75+
SPI0Command(SPI_FLASH_CMD_WRDI,NULL,0,0); // write disable - probably not needed
76+
}
77+
}
78+
}
79+
}
80+
81+
} // namespace experimental
82+
83+
#ifdef __cplusplus
84+
}
85+
#endif

cores/esp8266/core_esp8266_main.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extern "C" {
3434
}
3535
#include <core_version.h>
3636
#include "gdb_hooks.h"
37+
#include "flash_quirks.h"
3738

3839
#define LOOP_TASK_PRIORITY 1
3940
#define LOOP_QUEUE_SIZE 1
@@ -334,6 +335,8 @@ extern "C" void user_init(void) {
334335

335336
initVariant();
336337

338+
experimental::initFlashQuirks(); // Chip specific flash init.
339+
337340
cont_init(g_pcont);
338341

339342
preinit(); // Prior to C++ Dynamic Init (not related to above init() ). Meant to be user redefinable.

cores/esp8266/flash_quirks.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
flash_quirks.h
3+
Copyright (c) 2019 Mike Nix. All rights reserved.
4+
This file is part of the esp8266 core for Arduino environment.
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#ifndef FLASH_QUIRKS_H
22+
#define FLASH_QUIRKS_H
23+
24+
#ifdef __cplusplus
25+
extern "C" {
26+
#endif
27+
28+
#include "spi_vendors.h"
29+
#include "spi_flash_defs.h"
30+
31+
namespace experimental {
32+
33+
void initFlashQuirks();
34+
35+
} // namespace experimental
36+
37+
#ifdef __cplusplus
38+
}
39+
#endif
40+
41+
42+
#endif // FLASH_QUIRKS_H

0 commit comments

Comments
 (0)