Skip to content
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

Closed
Jason2866 opened this issue Aug 16, 2022 · 33 comments · Fixed by #7239
Closed

Flash mode is wrong identified with the API call #7140

Jason2866 opened this issue Aug 16, 2022 · 33 comments · Fixed by #7239
Assignees
Milestone

Comments

@Jason2866
Copy link
Collaborator

Jason2866 commented Aug 16, 2022

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 mode qio The info is fetched from magic byte in firmware.

FlashMode_t EspClass::getFlashChipMode(void)

Thx @s-hadinger for "finding" the corresponding code in Arduino

Used flash mode is activated from 2nd stage bootloader as can be seen here:

Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x1278
load:0x403cc710,len:0xb9c
load:0x403ce710,len:0x2b50
SHA-256 comparison failed:
Calculated: f526bbbf3f0d384062c796362385b439c9aa329972519fc8905554dff52750c9
Expected: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Attempting to boot anyway...
entry 0x403cc710
I (48) boot: ESP-IDF v4.4.3-145-g9ce849ce72 2nd stage bootloader
I (49) boot: compile time 11:08:46
I (49) boot: chip revision: 3
I (49) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (55) qio_mode: Enabling default flash chip QIO
I (59) boot.esp32c3: SPI Speed      : 80MHz
I (63) boot.esp32c3: SPI Mode       : QIO
I (67) boot.esp32c3: SPI Flash Size : 4MB
I (71) boot: Enabling RNG early entropy source...
I (75) boot: Partition Table:
I (78) boot: ## Label            Usage          Type ST Offset   Length
I (84) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (90) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (97) boot:  2 safeboot         factory app      00 00 00010000 000d0000
I (103) boot:  3 app0             OTA app          00 10 000e0000 002d0000
I (110) boot:  4 spiffs           Unknown data     01 82 003b0000 00050000
I (117) boot: End of partition table
I (120) esp_image: segment 0: paddr=000e0020 vaddr=3c100020 size=375c0h (226752) map
I (127) esp_image: segment 1: paddr=001175e8 vaddr=3fc8cc00 size=02dfch ( 11772) load
I (135) esp_image: segment 2: paddr=0011a3ec vaddr=40380000 size=05c2ch ( 23596) load
I (144) esp_image: segment 3: paddr=00120020 vaddr=42000020 size=f41d4h (999892) map
I (150) esp_image: segment 4: paddr=002141fc vaddr=40385c2c size=06f40h ( 28480) load
I (159) esp_image: segment 5: paddr=0021b144 vaddr=50000010 size=00010h (    16) load
I (165) boot: Loaded app from partition at offset 0xe0000
I (170) boot: Disabling RNG early entropy source...

00:00:00.000-253/08 HDW: ESP32-C3 
00:00:00.010-252/07 UFS: FlashFS mounted with 288 kB free
00:00:00.024 CFG: Loaded from File, Count 32
00:00:00.068 BRY: Berry initialized, RAM used=4215 bytes
00:00:00.075 Project sonoff - Tasmota Version 12.0.2.4(UNIVERSAL)-2_0_5_dev(2022-08-16T13:35:38)
00:00:00.097 TAP: Loaded Tasmota App 'Partition_Wizard.tapp'
00:00:00.959 WIF: Connecting to AP1 Jason_Home_WLAN Channel 11 BSSId 00:A0:57:2A:BD:19 in mode 11n as sonoff-A44FC0-4032...
00:00:06.064 WIF: Connected
00:00:06.317 HTP: Web server active on sonoff-A44FC0-4032 with IP address 192.168.2.178

Sketch

Every sketch builded in flash mode qio
For example https://github.com/Jason2866/ESP32_Show_Info

Debug Message

Enable Bootlogging is sdkkonfig and compile the arduino libs with.


Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x1278
load:0x403cc710,len:0xb9c
load:0x403ce710,len:0x2b50
SHA-256 comparison failed:
Calculated: f526bbbf3f0d384062c796362385b439c9aa329972519fc8905554dff52750c9
Expected: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Attempting to boot anyway...
entry 0x403cc710
I (48) boot: ESP-IDF v4.4.3-145-g9ce849ce72 2nd stage bootloader
I (49) boot: compile time 11:08:46
I (49) boot: chip revision: 3
I (49) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (55) qio_mode: Enabling default flash chip QIO
I (59) boot.esp32c3: SPI Speed      : 80MHz
I (63) boot.esp32c3: SPI Mode       : QIO
I (67) boot.esp32c3: SPI Flash Size : 4MB
I (71) boot: Enabling RNG early entropy source...
I (75) boot: Partition Table:
I (78) boot: ## Label            Usage          Type ST Offset   Length
I (84) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (90) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (97) boot:  2 safeboot         factory app      00 00 00010000 000d0000
I (103) boot:  3 app0             OTA app          00 10 000e0000 002d0000
I (110) boot:  4 spiffs           Unknown data     01 82 003b0000 00050000
I (117) boot: End of partition table
I (120) esp_image: segment 0: paddr=000e0020 vaddr=3c100020 size=375c0h (226752) map
I (127) esp_image: segment 1: paddr=001175e8 vaddr=3fc8cc00 size=02dfch ( 11772) load
I (135) esp_image: segment 2: paddr=0011a3ec vaddr=40380000 size=05c2ch ( 23596) load
I (144) esp_image: segment 3: paddr=00120020 vaddr=42000020 size=f41d4h (999892) map
I (150) esp_image: segment 4: paddr=002141fc vaddr=40385c2c size=06f40h ( 28480) load
I (159) esp_image: segment 5: paddr=0021b144 vaddr=50000010 size=00010h (    16) load
I (165) boot: Loaded app from partition at offset 0xe0000
I (170) boot: Disabling RNG early entropy source...

00:00:00.000-253/08 HDW: ESP32-C3 
00:00:00.010-252/07 UFS: FlashFS mounted with 288 kB free
00:00:00.024 CFG: Loaded from File, Count 32
00:00:00.068 BRY: Berry initialized, RAM used=4215 bytes
00:00:00.075 Project sonoff - Tasmota Version 12.0.2.4(UNIVERSAL)-2_0_5_dev(2022-08-16T13:35:38)
00:00:00.097 TAP: Loaded Tasmota App 'Partition_Wizard.tapp'
00:00:00.959 WIF: Connecting to AP1 Jason_Home_WLAN Channel 11 BSSId 00:A0:57:2A:BD:19 in mode 11n as sonoff-A44FC0-4032...
00:00:06.064 WIF: Connected
00:00:06.317 HTP: Web server active on sonoff-A44FC0-4032 with IP address 192.168.2.178Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x1278
load:0x403cc710,len:0xb9c
load:0x403ce710,len:0x2b50
SHA-256 comparison failed:
Calculated: f526bbbf3f0d384062c796362385b439c9aa329972519fc8905554dff52750c9
Expected: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Attempting to boot anyway...
entry 0x403cc710
I (48) boot: ESP-IDF v4.4.3-145-g9ce849ce72 2nd stage bootloader
I (49) boot: compile time 11:08:46
I (49) boot: chip revision: 3
I (49) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (55) qio_mode: Enabling default flash chip QIO
I (59) boot.esp32c3: SPI Speed      : 80MHz
I (63) boot.esp32c3: SPI Mode       : QIO
I (67) boot.esp32c3: SPI Flash Size : 4MB
I (71) boot: Enabling RNG early entropy source...
I (75) boot: Partition Table:
I (78) boot: ## Label            Usage          Type ST Offset   Length
I (84) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (90) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (97) boot:  2 safeboot         factory app      00 00 00010000 000d0000
I (103) boot:  3 app0             OTA app          00 10 000e0000 002d0000
I (110) boot:  4 spiffs           Unknown data     01 82 003b0000 00050000
I (117) boot: End of partition table
I (120) esp_image: segment 0: paddr=000e0020 vaddr=3c100020 size=375c0h (226752) map
I (127) esp_image: segment 1: paddr=001175e8 vaddr=3fc8cc00 size=02dfch ( 11772) load
I (135) esp_image: segment 2: paddr=0011a3ec vaddr=40380000 size=05c2ch ( 23596) load
I (144) esp_image: segment 3: paddr=00120020 vaddr=42000020 size=f41d4h (999892) map
I (150) esp_image: segment 4: paddr=002141fc vaddr=40385c2c size=06f40h ( 28480) load
I (159) esp_image: segment 5: paddr=0021b144 vaddr=50000010 size=00010h (    16) load
I (165) boot: Loaded app from partition at offset 0xe0000
I (170) boot: Disabling RNG early entropy source...

00:00:00.000-253/08 HDW: ESP32-C3 
00:00:00.010-252/07 UFS: FlashFS mounted with 288 kB free
00:00:00.024 CFG: Loaded from File, Count 32
00:00:00.068 BRY: Berry initialized, RAM used=4215 bytes
00:00:00.075 Project sonoff - Tasmota Version 12.0.2.4(UNIVERSAL)-2_0_5_dev(2022-08-16T13:35:38)
00:00:00.097 TAP: Loaded Tasmota App 'Partition_Wizard.tapp'
00:00:00.959 WIF: Connecting to AP1 Jason_Home_WLAN Channel 11 BSSId 00:A0:57:2A:BD:19 in mode 11n as sonoff-A44FC0-4032...
00:00:06.064 WIF: Connected
00:00:06.317 HTP: Web server active on sonoff-A44FC0-4032 with IP address 192.168.2.178


### Other Steps to Reproduce

_No response_

### I have checked existing issues, online documentation and the Troubleshooting Guide

- [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@Jason2866
Copy link
Collaborator Author

Jason2866 commented Aug 16, 2022

@VojtechBartoska This is a Arduino IDE issue, not Platformio. The code in Arduino does not work as it should.
PR #7141 is not related too.

@VojtechBartoska VojtechBartoska added Status: Needs investigation We need to do some research before taking next steps on this issue and removed Status: In Progress Issue is in progress IDE: PlaformIO Issue relates to PlatformIO IDE labels Aug 16, 2022
@VojtechBartoska
Copy link
Contributor

ah, okay. Edited. I did too quick check, sorry :)

@Jason2866
Copy link
Collaborator Author

Jason2866 commented Aug 22, 2022

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.

#include <Arduino.h>
#include "soc/spi_reg.h"

#if CONFIG_IDF_TARGET_ESP32
  #include "esp32/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32S2  // ESP32-S2
  #include "esp32s2/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32S3  // ESP32-S3
  #include "esp32s3/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32C3  // ESP32-C3
  #include "esp32c3/rom/spi_flash.h"
#endif

#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
  #ifndef REG_SPI_BASE
  #define REG_SPI_BASE(i)     (DR_REG_SPI1_BASE + (((i)>1) ? (((i)* 0x1000) + 0x20000) : (((~(i)) & 1)* 0x1000 )))
  #endif // REG_SPI_BASE
#endif // TARGET


String ESP_getFlashChipMode(void) {
#if CONFIG_IDF_TARGET_ESP32S2
const uint32_t spi_ctrl = REG_READ(PERIPHS_SPI_FLASH_CTRL);
#else
const uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
#endif
/* Not all of the following constants are already defined in older versions of spi_reg.h, so do it manually for now*/
if (spi_ctrl & BIT(24)) { //SPI_FREAD_QIO
    return F("QIO");
} else if (spi_ctrl & BIT(20)) { //SPI_FREAD_QUAD
    return F("QOUT");
} else if (spi_ctrl &  BIT(23)) { //SPI_FREAD_DIO
    return F("DIO");
} else if (spi_ctrl & BIT(14)) { // SPI_FREAD_DUAL
    return F("DOUT");
} else if (spi_ctrl & BIT(13)) { //SPI_FASTRD_MODE
    return F("Fast");
} else {
    return F("Slow");
}
return F("DOUT");
}

uint32_t ESP_getFlashChipId(void)
{
  uint32_t id = g_rom_flashchip.device_id;
  id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00);
  return id;
}

uint32_t ESP_getFlashChipRealSize(void)
{
  uint32_t id = (ESP_getFlashChipId() >> 16) & 0xFF;
  return 2 << (id - 1);
}

void setup() {

  Serial.begin(115200);
  ps_malloc(550 * 1024);
  uint8_t * buf = (uint8_t*)malloc(500 * 1024);
  if (buf == NULL)
    Serial.println("can't allocate memory with malloc\n");

    Serial.print("ESP32 SDK: "); Serial.println(ESP.getSdkVersion());
    Serial.print("ESP32 CPU FREQ: "); Serial.print(getCpuFrequencyMhz()); Serial.println(" MHz");
    Serial.print("ESP32 XTAL FREQ: "); Serial.print(getXtalFrequencyMhz()); Serial.println(" MHz");
    Serial.print("ESP32 APB FREQ: "); Serial.print(getApbFrequency() / 1000000.0, 1); Serial.println(" MHz");
    Serial.print("ESP32 FLASH CHIP ID: "); Serial.println(ESP_getFlashChipId());
    Serial.print("ESP32 FLASH REAL SIZE: "); Serial.print(ESP_getFlashChipRealSize() / (1024.0 * 1024), 2); Serial.println(" MB");
    Serial.print("ESP32 FLASH SIZE (MAGIC BYTE): "); Serial.print(ESP.getFlashChipSize() / (1024.0 * 1024), 2); Serial.println(" MB");
    Serial.print("ESP32 FLASH REAL MODE: "); Serial.println(ESP_getFlashChipMode());
    Serial.print("ESP32 FLASH MODE (MAGIC BYTE): "); Serial.print(ESP.getFlashChipMode()); Serial.println(", 0=QIO, 1=QOUT, 2=DIO, 3=DOUT");
    Serial.print("ESP32 RAM SIZE: "); Serial.print(ESP.getHeapSize() / 1024.0, 2); Serial.println(" KB");
    Serial.print("ESP32 FREE RAM: "); Serial.print(ESP.getFreeHeap() / 1024.0, 2); Serial.println(" KB");
    Serial.print("ESP32 MAX RAM ALLOC: "); Serial.print(ESP.getMaxAllocHeap() / 1024.0, 2); Serial.println(" KB");
    Serial.print("ESP32 FREE PSRAM: "); Serial.print(ESP.getFreePsram() / 1024.0, 2); Serial.println(" KB");
}

void loop() {
}

@me-no-dev I have opened PR #7159 for real Flash Size. Can you include the change for getting the real used flash mode?

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

String ESP_getFlashChipMode(void) {

Maybe better to have const __FlashStringHelper* as return value here.
This way you don't have a String(const __FlashStringHelper*) constructor added in the compiled binary for every return entry in the function.
Will save roughly 12 - 16 bytes (not sure which, have to check) per return statement in the build size.

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

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
}

@Jason2866
Copy link
Collaborator Author

Nice too!
Ahh the flash mode routine does NOT work with the ESP32-S2. It generates a crash. Dunno why?!

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

Ahh the flash mode routine does NOT work with the ESP32-S2. It generates a crash. Dunno why?!

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

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

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.
By the way, why don't we use the defines like SPI_FREAD_QUAD ?
In which platform are these not (yet) defined?
And if they aren't, are these relevant to the newer platforms like the -S2 etc?

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

Ah found your 'crash' in the redefine of the REG_SPI_BASE

#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 SPI_CTRL_REG(0)?
The defines relying on that register address are all using (1) when defining flash like defines.
For example:

#define PERIPHS_SPI_FLASH_CTRL                SPI_CTRL_REG(1)

Edit:
This also means the SPI_CLOCK_REG should be used with 1 like this:

  const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(1));

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

Apparently the C3 and S2 don't have the same flash modes as the standard ESP32 does.
My assumption of the "DOUT" as default is just a guess on those platforms.

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
}

TD-er added a commit to TD-er/ESPEasy that referenced this issue Aug 22, 2022
@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

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.

#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
#define FSPI 0
#define HSPI 1
#else
#define FSPI 1 //SPI bus attached to the flash (can use the same data lines but different SS)
#define HSPI 2 //SPI bus normally mapped to pins 12 - 15, but can be matrixed to any pins
#if CONFIG_IDF_TARGET_ESP32
#define VSPI 3 //SPI bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
#endif
#endif

So we should use FSPI to indicate the bus:

 const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(FSPI));

Edit:
Hmm looking through the code a bit more and came across this piece of code which initializes the default SPI instance in the Arduino env.

#if CONFIG_IDF_TARGET_ESP32
SPIClass SPI(VSPI);
#else
SPIClass SPI(FSPI);
#endif

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)
If it is, then I wonder what harm will be done when calling SPI.end()

@Jason2866
Copy link
Collaborator Author

Jason2866 commented Aug 22, 2022

@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
Thx for your help and tipps!

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

String ESP_getFlashChipMode(void) {
#if CONFIG_IDF_TARGET_ESP32S2
const uint32_t spi_ctrl = REG_READ(PERIPHS_SPI_FLASH_CTRL);
#else
const uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
#endif
/* Not all of the following constants are already defined in older versions of spi_reg.h, so do it manually for now*/
if (spi_ctrl & BIT(24)) { //SPI_FREAD_QIO
return F("QIO");
} else if (spi_ctrl & BIT(20)) { //SPI_FREAD_QUAD
return F("QOUT");
} else if (spi_ctrl & BIT(23)) { //SPI_FREAD_DIO
return F("DIO");
} else if (spi_ctrl & BIT(14)) { // SPI_FREAD_DUAL
return F("DOUT");
} else if (spi_ctrl & BIT(13)) { //SPI_FASTRD_MODE
return F("Fast");
} else {
return F("Slow");
}
return F("DOUT");
}

This part may now no longer crash, but it is not outputting the correct mode on ESP32-S2

@Jason2866
Copy link
Collaborator Author

Jason2866 commented Aug 22, 2022

IT does!. Tested with the framework with bootlog enabled. I get correct results for every MCUs in every supported flash mode.

Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x1250
load:0x4004c000,len:0xcc8
load:0x40050000,len:0x2f14
SHA-256 comparison failed:
Calculated: fd4f370d6f0552354afad525956a6459d76ba08a75b4cc7ec69e90642975d01c
Expected: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Attempting to boot anyway...
entry 0x4004c220
I (40) boot: ESP-IDF v4.4.3-146-geafe239872 2nd stage bootloader
I (40) boot: compile time 18:38:53
I (40) boot: chip revision: 0
I (41) qio_mode: Enabling default flash chip QIO
I (45) boot.esp32s2: SPI Speed      : 80MHz
I (49) boot.esp32s2: SPI Mode       : QIO
I (53) boot.esp32s2: SPI Flash Size : 4MB
I (56) boot: Enabling RNG early entropy source...
I (61) boot: Partition Table:
I (64) boot: ## Label            Usage          Type ST Offset   Length
I (70) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (76) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (83) boot:  2 app0             OTA app          00 10 00010000 00140000
I (89) boot:  3 app1             OTA app          00 11 00150000 00140000
I (96) boot:  4 spiffs           Unknown data     01 82 00290000 00170000
I (102) boot: End of partition table
I (106) esp_image: segment 0: paddr=00010020 vaddr=3f000020 size=022e0h (  8928) map
I (113) esp_image: segment 1: paddr=00012308 vaddr=3ffbde70 size=011c0h (  4544) load
I (121) esp_image: segment 2: paddr=000134d0 vaddr=40024000 size=09e64h ( 40548) load
I (131) esp_image: segment 3: paddr=0001d33c vaddr=50000400 size=00010h (    16) load
I (136) esp_image: segment 4: paddr=0001d354 vaddr=00000000 size=02cc4h ( 11460) 
I (143) esp_image: segment 5: paddr=00020020 vaddr=40080020 size=0fa4ch ( 64076) map
I (150) boot: Loaded app from partition at offset 0x10000
I (156) boot: Disabling RNG early entropy source...
ESP32 SDK: v4.4.3-146-geafe239872
ESP32 CPU FREQ: 240 MHz
ESP32 XTAL FREQ: 40 MHz
ESP32 APB FREQ: 80.0 MHz
ESP32 FLASH CHIP ID: 1458208
ESP32 FLASH REAL SIZE: 4.00 MB
ESP32 FLASH SIZE (MAGIC BYTE): 4.00 MB
ESP32 FLASH REAL MODE: QIO
ESP32 FLASH MODE (MAGIC BYTE): 2, 0=QIO, 1=QOUT, 2=DIO, 3=DOUT
ESP32 RAM SIZE: 255.97 KB
ESP32 FREE RAM: 237.61 KB
ESP32 MAX RAM ALLOC: 211.99 KB
ESP32 FREE PSRAM: 7139.33 KB

Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DOUT, clock div:1
load:0x3ffe6100,len:0x1250
load:0x4004c000,len:0xcc8
load:0x40050000,len:0x2f14
SHA-256 comparison failed:
Calculated: 519e212091b8cf87bb9dd4e6939cd11730966840f324936fc1f939c96b1731ba
Expected: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Attempting to boot anyway...
entry 0x4004c220
I (40) boot: ESP-IDF v4.4.3-146-geafe239872 2nd stage bootloader
I (40) boot: compile time 18:39:03
I (40) boot: chip revision: 0
I (41) qio_mode: Enabling default flash chip QIO
I (45) boot.esp32s2: SPI Speed      : 80MHz
I (49) boot.esp32s2: SPI Mode       : QOUT
I (53) boot.esp32s2: SPI Flash Size : 4MB
I (57) boot: Enabling RNG early entropy source...
I (61) boot: Partition Table:
I (64) boot: ## Label            Usage          Type ST Offset   Length
I (70) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (77) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (83) boot:  2 app0             OTA app          00 10 00010000 00140000
I (90) boot:  3 app1             OTA app          00 11 00150000 00140000
I (96) boot:  4 spiffs           Unknown data     01 82 00290000 00170000
I (103) boot: End of partition table
I (106) esp_image: segment 0: paddr=00010020 vaddr=3f000020 size=022e0h (  8928) map
I (113) esp_image: segment 1: paddr=00012308 vaddr=3ffbde70 size=011c0h (  4544) load
I (121) esp_image: segment 2: paddr=000134d0 vaddr=40024000 size=09e64h ( 40548) load
I (132) esp_image: segment 3: paddr=0001d33c vaddr=50000400 size=00010h (    16) load
I (136) esp_image: segment 4: paddr=0001d354 vaddr=00000000 size=02cc4h ( 11460) 
I (143) esp_image: segment 5: paddr=00020020 vaddr=40080020 size=0fa4ch ( 64076) map
I (151) boot: Loaded app from partition at offset 0x10000
I (156) boot: Disabling RNG early entropy source...
ESP32 SDK: v4.4.3-146-geafe239872
ESP32 CPU FREQ: 240 MHz
ESP32 XTAL FREQ: 40 MHz
ESP32 APB FREQ: 80.0 MHz
ESP32 FLASH CHIP ID: 1458208
ESP32 FLASH REAL SIZE: 4.00 MB
ESP32 FLASH SIZE (MAGIC BYTE): 4.00 MB
ESP32 FLASH REAL MODE: QOUT
ESP32 FLASH MODE (MAGIC BYTE): 3, 0=QIO, 1=QOUT, 2=DIO, 3=DOUT
ESP32 RAM SIZE: 255.97 KB
ESP32 FREE RAM: 237.61 KB
ESP32 MAX RAM ALLOC: 211.99 KB
ESP32 FREE PSRAM: 7139.33 KB

Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x1118
load:0x4004c000,len:0xa38
load:0x40050000,len:0x2db8
SHA-256 comparison failed:
Calculated: 583171cfcf53b476ea0f35c843152f0cb62cf7ffe0c569ff2841ec51dae80fff
Expected: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Attempting to boot anyway...
entry 0x4004c1f8
I (40) boot: ESP-IDF v4.4.3-146-geafe239872 2nd stage bootloader
I (40) boot: compile time 18:39:12
I (40) boot: chip revision: 0
I (41) boot.esp32s2: SPI Speed      : 80MHz
I (45) boot.esp32s2: SPI Mode       : DIO
I (48) boot.esp32s2: SPI Flash Size : 4MB
I (52) boot: Enabling RNG early entropy source...
I (57) boot: Partition Table:
I (59) boot: ## Label            Usage          Type ST Offset   Length
I (66) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (72) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (79) boot:  2 app0             OTA app          00 10 00010000 00140000
I (85) boot:  3 app1             OTA app          00 11 00150000 00140000
I (92) boot:  4 spiffs           Unknown data     01 82 00290000 00170000
I (98) boot: End of partition table
I (101) esp_image: segment 0: paddr=00010020 vaddr=3f000020 size=022e0h (  8928) map
I (109) esp_image: segment 1: paddr=00012308 vaddr=3ffbde70 size=011c0h (  4544) load
I (117) esp_image: segment 2: paddr=000134d0 vaddr=40024000 size=09e64h ( 40548) load
I (128) esp_image: segment 3: paddr=0001d33c vaddr=50000400 size=00010h (    16) load
I (131) esp_image: segment 4: paddr=0001d354 vaddr=00000000 size=02cc4h ( 11460) 
I (139) esp_image: segment 5: paddr=00020020 vaddr=40080020 size=0fa4ch ( 64076) map
I (146) boot: Loaded app from partition at offset 0x10000
I (151) boot: Disabling RNG early entropy source...
ESP32 SDK: v4.4.3-146-geafe239872
ESP32 CPU FREQ: 240 MHz
ESP32 XTAL FREQ: 40 MHz
ESP32 APB FREQ: 80.0 MHz
ESP32 FLASH CHIP ID: 1458208
ESP32 FLASH REAL SIZE: 4.00 MB
ESP32 FLASH SIZE (MAGIC BYTE): 4.00 MB
ESP32 FLASH REAL MODE: DIO
ESP32 FLASH MODE (MAGIC BYTE): 2, 0=QIO, 1=QOUT, 2=DIO, 3=DOUT
ESP32 RAM SIZE: 255.97 KB
ESP32 FREE RAM: 237.61 KB
ESP32 MAX RAM ALLOC: 211.99 KB
ESP32 FREE PSRAM: 7139.33 KB

ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DOUT, clock div:1
load:0x3ffe6100,len:0x1118
load:0x4004c000,len:0xa38
load:0x40050000,len:0x2db8
SHA-256 comparison failed:
Calculated: ed8c1c37cd07dc0422bc52a3d05c469488d38c8a7f2dd2512388677d69a815a0
Expected: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Attempting to boot anyway...
entry 0x4004c1f8
I (40) boot: ESP-IDF v4.4.3-146-geafe239872 2nd stage bootloader
I (40) boot: compile time 18:39:22
I (40) boot: chip revision: 0
I (41) boot.esp32s2: SPI Speed      : 80MHz
I (45) boot.esp32s2: SPI Mode       : DOUT
I (48) boot.esp32s2: SPI Flash Size : 4MB
I (52) boot: Enabling RNG early entropy source...
I (57) boot: Partition Table:
I (59) boot: ## Label            Usage          Type ST Offset   Length
I (66) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (72) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (79) boot:  2 app0             OTA app          00 10 00010000 00140000
I (85) boot:  3 app1             OTA app          00 11 00150000 00140000
I (92) boot:  4 spiffs           Unknown data     01 82 00290000 00170000
I (98) boot: End of partition table
I (102) esp_image: segment 0: paddr=00010020 vaddr=3f000020 size=022e0h (  8928) map
I (109) esp_image: segment 1: paddr=00012308 vaddr=3ffbde70 size=011c0h (  4544) load
I (117) esp_image: segment 2: paddr=000134d0 vaddr=40024000 size=09e64h ( 40548) load
I (129) esp_image: segment 3: paddr=0001d33c vaddr=50000400 size=00010h (    16) load
I (132) esp_image: segment 4: paddr=0001d354 vaddr=00000000 size=02cc4h ( 11460) 
I (139) esp_image: segment 5: paddr=00020020 vaddr=40080020 size=0fa4ch ( 64076) map
I (146) boot: Loaded app from partition at offset 0x10000
I (151) boot: Disabling RNG early entropy source...
ESP32 SDK: v4.4.3-146-geafe239872
ESP32 CPU FREQ: 240 MHz
ESP32 XTAL FREQ: 40 MHz
ESP32 APB FREQ: 80.0 MHz
ESP32 FLASH CHIP ID: 1458208
ESP32 FLASH REAL SIZE: 4.00 MB
ESP32 FLASH SIZE (MAGIC BYTE): 4.00 MB
ESP32 FLASH REAL MODE: DOUT
ESP32 FLASH MODE (MAGIC BYTE): 3, 0=QIO, 1=QOUT, 2=DIO, 3=DOUT
ESP32 RAM SIZE: 255.97 KB
ESP32 FREE RAM: 237.61 KB
ESP32 MAX RAM ALLOC: 211.99 KB
ESP32 FREE PSRAM: 7139.33 KB

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

OK, which modes did you test?
The spi_reg.h file for ESP32s2 does suggest different bit nr for SPI_FREAD_QUAD for example.

ESP32:

/* 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

ESP32-S2:

/* 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

@Jason2866
Copy link
Collaborator Author

Jason2866 commented Aug 22, 2022

See above logs, it just works for all modes ;-)

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

See above logs, it just works for all modes ;-)

I do see it in the logs, but that implies I don't understand it. :(

@Jason2866
Copy link
Collaborator Author

Yeah, i see what you have posted and with this info it is a miracle why it works!

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

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 ;)

@TD-er
Copy link
Contributor

TD-er commented Aug 22, 2022

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.

#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
#define FSPI 0
#define HSPI 1
#else
#define FSPI 1 //SPI bus attached to the flash (can use the same data lines but different SS)
#define HSPI 2 //SPI bus normally mapped to pins 12 - 15, but can be matrixed to any pins
#if CONFIG_IDF_TARGET_ESP32
#define VSPI 3 //SPI bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
#endif
#endif

So we should use FSPI to indicate the bus:

 const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(FSPI));

Edit: Hmm looking through the code a bit more and came across this piece of code which initializes the default SPI instance in the Arduino env.

#if CONFIG_IDF_TARGET_ESP32
SPIClass SPI(VSPI);
#else
SPIClass SPI(FSPI);
#endif

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) If it is, then I wonder what harm will be done when calling SPI.end()

Still looking into this part and I got the impression that this init of the SPI(FSPI) for other platforms than the traditional ESP32 is a typo.
Looks like it should be HSPI since there is no VSPI for the others.

@me-no-dev
Copy link
Member

Still looking into this part and I got the impression that this init of the SPI(FSPI) for other platforms than the traditional ESP32 is a typo.
Looks like it should be HSPI since there is no VSPI for the others.

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

@TD-er
Copy link
Contributor

TD-er commented Aug 23, 2022

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)
But why then re-use the FSPI name on other boards which do not have this bus connected to the flash/PSRAM?
If there is something in the naming of the busses which I misinterpret, please explain what it is.

@Jason2866
Copy link
Collaborator Author

@TD-er Your code snipplet to get the actual flash frequency seems not to work correctly.
It says here 40 Mhz which is wrong.

entry 0x40080694
I (29) boot: ESP-IDF v4.4.3-146-geafe239872 2nd stage bootloader
I (29) boot: compile time 18:55:48
I (29) boot: chip revision: 1
I (30) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (36) qio_mode: Enabling default flash chip QIO
I (40) boot.esp32: SPI Speed      : 80MHz
I (44) boot.esp32: SPI Mode       : QIO
I (48) boot.esp32: SPI Flash Size : 4MB
I (51) boot: Enabling RNG early entropy source...
I (56) boot: Partition Table:
I (58) boot: ## Label            Usage          Type ST Offset   Length
I (65) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (71) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (78) boot:  2 app0             OTA app          00 10 00010000 00140000
I (84) boot:  3 app1             OTA app          00 11 00150000 00140000
I (91) boot:  4 spiffs           Unknown data     01 82 00290000 00170000
I (97) boot: End of partition table
I (101) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=028bch ( 10428) map
I (108) esp_image: segment 1: paddr=000128e4 vaddr=3ffbdb60 size=02c08h ( 11272) load
I (116) esp_image: segment 2: paddr=000154f4 vaddr=40080000 size=0ab24h ( 43812) load
I (126) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=10f30h ( 69424) map
I (130) esp_image: segment 4: paddr=00030f58 vaddr=4008ab24 size=023fch (  9212) load
I (139) esp_image: segment 5: paddr=0003335c vaddr=50000400 size=00010h (    16) load
I (146) boot: Loaded app from partition at offset 0x10000
I (151) boot: Disabling RNG early entropy source...
can't allocate memory with malloc

ESP32 SDK: v4.4.3-146-geafe239872
ESP32 DEVICE: ESP32-D0WDQ6 rev.1
ESP32 CPU FREQ: 240 MHz
ESP32 XTAL FREQ: 40 MHz
ESP32 APB FREQ: 80.0 MHz
ESP32 FLASH CHIP ID: 1458392
ESP32 FLASH CHIP FREQ: 40.0 MHz
ESP32 FLASH REAL SIZE: 4.00 MB
ESP32 FLASH SIZE (MAGIC BYTE): 4.00 MB
ESP32 FLASH REAL MODE: QIO
ESP32 FLASH MODE (MAGIC BYTE): 2, 0=QIO, 1=QOUT, 2=DIO, 3=DOUT
ESP32 RAM SIZE: 366.14 KB
ESP32 FREE RAM: 342.50 KB
ESP32 MAX RAM ALLOC: 119.99 KB
ESP32 FREE PSRAM: 0.00 KB

@TD-er
Copy link
Contributor

TD-er commented Aug 25, 2022

@TD-er Your code snipplet to get the actual flash frequency seems not to work correctly.
It says here 40 Mhz which is wrong.

Not saying it is impossible (or even improbable) that my code snippet is incorrect.
But given the other issues we've seen, are we sure the reported speed in the 2nd stage bootloader represents the actual mode/settings used after the bootloader is done?
Are these pins accesssible from the outside of the module?
I do have one of those older boards, so I can hook up something to actually see the frequency.

@Jason2866
Copy link
Collaborator Author

True (again). Do not trust anything. So only connecting hardware and measure is the way to be correct and safe.

@TD-er
Copy link
Contributor

TD-er commented Aug 28, 2022

I do have an opposite situation here on my test board.
Settings were set to 40 MHz and I even flashed it using the Espressif download tool using the DoNotChangeBin option checked.
But my detection algorithm outputs 80 MHz.
image

So tomorrow I will try to hook up a probe to the SPI clock pin.
image

Shoud be on GPIO-6 right?
Let's hope my probing tools will leave enough of the signal in tact so the ESP will even continue to work.

@TD-er
Copy link
Contributor

TD-er commented Aug 28, 2022

N.B. I just OTA updated another board (with 16M flash) which was previously flashed using DOUT and 40 MHz.
Now this board shows 80 MHz too, where it was reporting 40 MHz from a previous build.
Not sure if I can access the flash connected pins on that board, but will try to measure that one too.

The mode on that board is now also reported to be DIO, where it was DOUT and I did not update the bootloader.
image

@Jason2866
Copy link
Collaborator Author

Looking curious forward seeing your measured results!

@TD-er
Copy link
Contributor

TD-er commented Aug 29, 2022

Well my measurements are absolutely not conclusive.

I logged the SPI clock during boot.
There are longer bursts of data and then every now and then it seems to poll for short bursts of data like this:
image
That's for sure 80 MHz, but these are very short and happen every 86.29 usec
image
This is roughly 100 msec after the first clock pulses occur after boot.

When looking at the other data transfers, I see 40 MHz:
image

And at point in the measurement where I know for sure my code is running, the SPI clock seems to be 40 MHz:
image

Edit:
Just to make sure it wasn't just probing for PSRAM, this is one such section decoded SPI:
image
The CS pin (GPIO-11, SPI_CS0) for the internal flash was low, so that one was addressed and not another device on the same bus.

N.B. the data on the green and blue line are connected to:

  • Green: GPIO-7, SPI_Q
  • Blue: GPIO-8, SPI_D
  • Yellow: GPIO-6, SPI_CLK
  • Purple: GPIO-11, SPI_CS0

My logic analyzer does not support DIO/QIO like decoding, so they are just there to see if we see any data at all.
The decoded data doesn't make sense for obvious reasons.

@TD-er
Copy link
Contributor

TD-er commented Aug 29, 2022

When I switch the index to 0 for the SPI_CLOCK_REG, I do seem to get the correct 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();
  }
  return spiClockDivToFrequency(spi_clock);
  #endif // ifdef ESP8266
}

However on this board, I can't get the flash to run at 80 MHz.
Setting the flash freq. to 80 MHz and flashing it via esptool, or the Espressif download tool with the do not change bin checked, does not make any difference.
The reported "IDE" speed is 80 MHz, but the reported frequency using above function and using the logic analyzer do both show 40 MHz.

However there are still these very short transfers periodically running at 80 MHz:
image

They only communicate like 2 transfers (16-ish clock pulses)
image

So I have no clue what these are for, nor why these run at 80 MHz.
These also occur when setting the board frequency to 40 MHz.

Maybe someone with more deeper knowledge of the inner workings of the ESP32 can explain what's happening here?

@Jason2866
Copy link
Collaborator Author

Can of worms. Probably related #7192

@TD-er
Copy link
Contributor

TD-er commented Aug 29, 2022

I've looked a bit more through the code and it seems that on each spiTransaction call you will set the clock settings.
Thus if for whatever reason this clockDiv value is somewhere cached, not updated or not kept in sync with the rest, you can see changes in SPI frequency.

void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder)
{
if(!spi) {
return;
}
SPI_MUTEX_LOCK();
spi->dev->clock.val = clockDiv;

Here the clock union struct:

union {
struct {
uint32_t clkcnt_l: 6; /*In the master mode it must be equal to spi_clkcnt_N. In the slave mode it must be 0.*/
uint32_t clkcnt_h: 6; /*In the master mode it must be floor((spi_clkcnt_N+1)/2-1). In the slave mode it must be 0.*/
uint32_t clkcnt_n: 6; /*In the master mode it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/
uint32_t clkdiv_pre: 13; /*In the master mode it is pre-divider of spi_clk.*/
uint32_t clk_equ_sysclk: 1; /*In the master mode 1: spi_clk is eqaul to system 0: spi_clk is divided from system clock.*/
};
uint32_t val;
} clock;

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.
I'm not 100% sure if my call to REG_READ(SPI_CLOCK_REG(0)); does read this struct directly or not.
If not, then I wonder what calls to write do as that's a good receipe for state of the flash chip and this struct to get out of sync.

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.
Now I have to assume (a lot of) things and it is next to impossible to draw conclusions on assumptions.... well conclusions with some foundation at least ;)

@TD-er
Copy link
Contributor

TD-er commented Aug 29, 2022

Have been testing a bit to make sure which SPI bus is connected to the flash.
When setting SPI bus 0 to 80 or 20 MHz, the ESP does nicely crash (as I would expect), but at least I could see the clock was actually set to this frequency I programmed it to have.

 #include <soc/spi_struct.h>

 SPI0.clock.val = spiFrequencyToClockDiv(20000000L);

image

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
Is SPI bus 0 always the bus which is connected to the flash?

Repository owner moved this from Todo to Done in Arduino ESP32 Core Project Roadmap Sep 14, 2022
@mrengineer7777 mrengineer7777 added Status: Solved and removed Status: Needs investigation We need to do some research before taking next steps on this issue labels May 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment