-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flash mode is wrong identified with the API call #7140
Comments
@VojtechBartoska This is a Arduino IDE issue, not Platformio. The code in Arduino does not work as it should. |
ah, okay. Edited. I did too quick check, sorry :) |
This demo sketch has solutions to show real flash size and flash mode. The values are NOT fetched from the header (magic bytes). Thx for the solution goes to @Staars and @TD-er EDIT: Changed the code example, since it crashed for the S2. This is fixed now.
@me-no-dev I have opened PR #7159 for real Flash Size. Can you include the change for getting the real used flash mode? |
Maybe better to have |
Maybe also nice to add a function to compute the flash frequency: uint32_t getFlashChipSpeed() {
#ifdef ESP8266
return ESP.getFlashChipSpeed();
#else // ifdef ESP8266
const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(0));
if (spi_clock & BIT(31)) {
// spi_clk is equal to system clock
return getApbFrequency();
}
/* SPI_CLKCNT_N : R/W ;bitpos:[17:12] ;default: 6'h3 ; */
// description: In the master mode it is the divider of spi_clk.
// So spi_clk frequencyis system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)
const uint32_t spi_clkdiv_pre = (spi_clock >> 18) & 0x1FFF;
const uint32_t spi_clkcnt_n = (spi_clock >> 12) & 0x3F;
return (getApbFrequency() / (spi_clkdiv_pre + 1)) / (spi_clkcnt_n + 1);
#endif // ifdef ESP8266
} |
Nice too! |
Not sure why it crashes, but I do see there is some differences in the used bits For example: (ESP32 first, then ESP32-S2) /* SPI_FREAD_QUAD : R/W ;bitpos:[20] ;default: 1'b0 ; */
/*description: In the read operations read-data phase apply 4 signals. 1: enable 0: disable.*/
#define SPI_FREAD_QUAD (BIT(20))
#define SPI_FREAD_QUAD_M (BIT(20))
#define SPI_FREAD_QUAD_V 0x1
#define SPI_FREAD_QUAD_S 20
/* SPI_FREAD_QUAD : R/W ;bitpos:[15] ;default: 1'b0 ; */
/*description: In the read operations read-data phase apply 4 signals. 1: enable
0: disable. Can be configured in CONF state.*/
#define SPI_FREAD_QUAD (BIT(15))
#define SPI_FREAD_QUAD_M (BIT(15))
#define SPI_FREAD_QUAD_V 0x1
#define SPI_FREAD_QUAD_S 15 There are even "OCT" values for the read mode on ESP32-S2 |
Found a function + macro on esp32-hal-spi.c which does make my SPI flash freq. even simpler. uint32_t getFlashChipSpeed() {
#ifdef ESP8266
return ESP.getFlashChipSpeed();
#else // ifdef ESP8266
const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(0));
if (spi_clock & BIT(31)) {
// spi_clk is equal to system clock
return getApbFrequency();
}
return spiClockDivToFrequency(spi_clock);
#endif // ifdef ESP8266
} Now have to look for a similar function for ESP32-S2 etc. for the flash mode. |
Ah found your 'crash' in the redefine of the #ifndef REG_SPI_BASE
#define REG_SPI_BASE(i) (DR_REG_SPI1_BASE + (((i)>1) ? (((i)* 0x1000) + 0x20000) : (((~(i)) & 1)* 0x1000 )))
#endif
#define REG_SPI_BASE(i) (DR_REG_SPI2_BASE + (((i)>3) ? (((i-2)* 0x1000) + 0x10000) : ((i - 2)* 0x1000 ))) Top one is from your suggested code, bottom one is how it is defined for the ESP32-S2 Another point of attention is why your code suggests to use #define PERIPHS_SPI_FLASH_CTRL SPI_CTRL_REG(1) Edit: const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(1)); |
Apparently the C3 and S2 don't have the same flash modes as the standard ESP32 does. const __FlashStringHelper* getFlashChipMode() {
#ifdef ESP8266
switch (ESP.getFlashChipMode()) {
case FM_QIO: return F("QIO");
case FM_QOUT: return F("QOUT");
case FM_DIO: return F("DIO");
case FM_DOUT: return F("DOUT");
}
return F("Unknown");
#else // ifdef ESP8266
// Source: https://github.com/letscontrolit/ESPEasy/pull/4200#issuecomment-1221607332
const uint32_t spi_ctrl = REG_READ(PERIPHS_SPI_FLASH_CTRL);
# if ESP_IDF_VERSION_MAJOR > 3 // IDF 4+
# if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
if (spi_ctrl & SPI_FREAD_QIO) {
return F("QIO");
} else if (spi_ctrl & SPI_FREAD_QUAD) {
return F("QOUT");
} else if (spi_ctrl & SPI_FREAD_DIO) {
return F("DIO");
} else if (spi_ctrl & SPI_FREAD_DUAL) {
return F("DOUT");
} else if (spi_ctrl & SPI_FASTRD_MODE) {
return F("Fast");
}
return F("Slow");
# elif CONFIG_IDF_TARGET_ESP32S2 // ESP32-S2
if (spi_ctrl & SPI_FREAD_OCT) {
return F("OCT");
} else if (spi_ctrl & SPI_FREAD_QUAD) {
return F("QIO");
} else if (spi_ctrl & SPI_FREAD_DUAL) {
return F("DIO");
}
return F("DOUT");
# elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3
if (spi_ctrl & SPI_FREAD_QUAD) {
return F("QIO");
} else if (spi_ctrl & SPI_FREAD_DUAL) {
return F("DIO");
}
return F("DOUT");
# endif // if CONFIG_IDF_TARGET_ESP32
# else // ESP32 Before IDF 4.0
if (spi_ctrl & (BIT(24))) {
return F("QIO");
} else if (spi_ctrl & (BIT(20))) {
return F("QOUT");
} else if (spi_ctrl & (BIT(23))) {
return F("DIO");
} else if (spi_ctrl & (BIT(14))) {
return F("DOUT");
} else if (spi_ctrl & (BIT(13))) {
return F("Fast");
}
return F("Slow");
# endif // if ESP_IDF_VERSION_MAJOR > 3
#endif // ifdef ESP8266
} |
Dug a bit more into the code. Apparently there are some nice defines to show what SPI bus should be connected to the flash memory. arduino-esp32/cores/esp32/esp32-hal-spi.h Lines 28 to 37 in fdf8389
So we should use const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(FSPI)); Edit: arduino-esp32/libraries/SPI/src/SPI.cpp Lines 346 to 350 in fdf8389
This does seem like it does initialize the same SPI bus as used for flash, or am I missing something? (on ESP32-S2/C3 etc) |
@TD-er Fixed the S2 crash it in my code example above. I know not the cleanest way... But it is working for all MCUs |
This part may now no longer crash, but it is not outputting the correct mode on ESP32-S2 |
IT does!. Tested with the framework with bootlog enabled. I get correct results for every MCUs in every supported flash mode.
|
OK, which modes did you test? ESP32: arduino-esp32/tools/sdk/esp32/include/soc/esp32/include/soc/spi_reg.h Lines 179 to 184 in 3f69bcf
ESP32-S2:
|
See above logs, it just works for all modes ;-) |
I do see it in the logs, but that implies I don't understand it. :( |
Yeah, i see what you have posted and with this info it is a miracle why it works! |
Glad we agree we both don't know what we're doing ;) |
Still looking into this part and I got the impression that this init of the |
There is no typo. ESP32 does not have FSPI, so VSPI is used as first bus. The rest use FSPI and ALL leave HSPI as second bus. This does not conflict with Flash and PSRAM on any of the chips. They use other SPI busses |
OK, but then the naming schema of the *SPI defines does seem a bit odd. From esp32-hal-spi.h: #define FSPI 1 //SPI bus attached to the flash (can use the same data lines but different SS) So given the comment, it is a perfectly fine name for the SPI bus, with F and "flash". I also searched for the differences between VSPI and HSPI and there seems to be none, even though the name does somewhat suggest a speed difference (at least to me) |
@TD-er Your code snipplet to get the actual flash frequency seems not to work correctly.
|
Not saying it is impossible (or even improbable) that my code snippet is incorrect. |
True (again). Do not trust anything. So only connecting hardware and measure is the way to be correct and safe. |
Looking curious forward seeing your measured results! |
Can of worms. Probably related #7192 |
I've looked a bit more through the code and it seems that on each arduino-esp32/cores/esp32/esp32-hal-spi.c Lines 1089 to 1095 in 77065bf
Here the arduino-esp32/tools/sdk/esp32/include/soc/esp32/include/soc/spi_struct.h Lines 99 to 108 in 77065bf
I wonder if the SPI bus may be accessed via other routes too and if so, the SPI frequency may be not as const as one might hope. Also I wonder if there are defines to know for sure which SPI bus is connected to what (e.g. flash/HSPI/VSPI) on each platform. |
Have been testing a bit to make sure which SPI bus is connected to the flash. #include <soc/spi_struct.h>
SPI0.clock.val = spiFrequencyToClockDiv(20000000L); So this way I know for sure it should be SPI bus 0 and not 1 as suggested by the comments next to the define of FSPI. So I guess that may also explain why the mode may not always be correctly identified. @me-no-dev |
Board
All ESP32x boards supporting Flash mode
qio
Device Description
Not relevant
Hardware Configuration
nothing connected
Version
v2.0.4
IDE Name
Platformio (custom self build)
Operating System
macOS 12.5
Flash frequency
80
PSRAM enabled
no
Upload speed
115200
Description
Calling the API to get flash mode info gives the result
dio
which is wrong when device is really running in modeqio
The info is fetched from magic byte in firmware.arduino-esp32/cores/esp32/Esp.cpp
Line 326 in 8ee5f0a
Thx @s-hadinger for "finding" the corresponding code in Arduino
Used flash mode is activated from 2nd stage bootloader as can be seen here:
Sketch
Every sketch builded in flash mode
qio
For example https://github.com/Jason2866/ESP32_Show_Info
Debug Message
The text was updated successfully, but these errors were encountered: