Possibility to use 120MHz flash setting for ESP32S3

Hello there,
I’m trying to figure out a way to set the 120MHz flash speed setting in the .ini file for esp32s3, namely speaking the “board_build.f_flash”.
To be exact the board is ESP32-S3-WROOM-2 M0N32R8V.

Browsing the files I’ve found:

esp32s3.menu.FlashMode.qio=QIO 80MHz
esp32s3.menu.FlashMode.qio.build.flash_mode=dio
esp32s3.menu.FlashMode.qio.build.boot=qio
esp32s3.menu.FlashMode.qio.build.boot_freq=80m
esp32s3.menu.FlashMode.qio.build.flash_freq=80m
esp32s3.menu.FlashMode.qio120=QIO 120MHz
esp32s3.menu.FlashMode.qio120.build.flash_mode=dio
esp32s3.menu.FlashMode.qio120.build.boot=qio
esp32s3.menu.FlashMode.qio120.build.boot_freq=120m
esp32s3.menu.FlashMode.qio120.build.flash_freq=80m
esp32s3.menu.FlashMode.dio=DIO 80MHz
esp32s3.menu.FlashMode.dio.build.flash_mode=dio
esp32s3.menu.FlashMode.dio.build.boot=dio
esp32s3.menu.FlashMode.dio.build.boot_freq=80m
esp32s3.menu.FlashMode.dio.build.flash_freq=80m
esp32s3.menu.FlashMode.opi=OPI 80MHz
esp32s3.menu.FlashMode.opi.build.flash_mode=dout
esp32s3.menu.FlashMode.opi.build.boot=opi
esp32s3.menu.FlashMode.opi.build.boot_freq=80m
esp32s3.menu.FlashMode.opi.build.flash_freq=80m

in .platformio/packages/framework-arduinoespressif32

I’ve based my understanding on DT’s and SPI Flash and External SPI RAM Configuration - ESP32-S3 - — ESP-IDF Programming Guide latest documentation

I think this can be done in esp-idf. I tried to edit the esptool.py, I was able to accept the bootloader but the settings are rejected:


Is there anyone out there that has done this, is it even possible?

It looks like you can use board_build.arduino.custom_bootloader property to swap bootloader in your platformio.ini file. The path is evaluated from variants/board directory, which means you must go up two levels in the directory structure and then apply tools\sdk\platform\bin.

In your platformio.ini file put this line:

board_build.arduino.custom_bootloader = ..\..\tools\sdk\esp32s3\bin\bootloader_qio_120m.elf

Be aware as this seems to be experimental feature and remember this setting may override your flash/psram SPI settings.

PS: Arduino flash speed detection is done via switch-based function which relies on chip ID rather than real hardware settings.

Hello @cziter15 its been some time and the changes I made to the esptool.py got lost somewhere. Could you provide a full .ini file that uses the custom boot loader with the 120Mhz flash speed setting ?

I would be very grate full !
Thank you

I don’t have any project using 120m atm, but here’s the line:

board_build.arduino.custom_bootloader = …..\tools\sdk\esp32s3\bin\bootloader_qio_120m.elf

Using this you can swap bootloader to the 120m variant. Place this in your environment section of platformio.ini file.

I’m not sure how to test it as standard Arduino function uses chip id to get it’s frequency (not real value). Maybe some kind of bandwidth testing should be implemented to verify speed improvement. Maybe there’s a native esp function to read it. I didn’t have time to get deeper insight. Moreover it seems like experimental and there’s some info that temperature increase may affect flash operability when using 120Mhz.

OK so i tested it with this setting:

[env:latest_stable]
platform = https://github.com/platformio/platform-espressif32.git
framework = arduino
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
;board_build.arduino.memory_type =qio_qspi; qio120 ;opi_opi ;"qio_qspi"
board_build.f_flash = 120000000L
;board_build.flash_mode = qio
board_build.partitions = lib/file_system/custom32MB_partition.csv
board_build.arduino.custom_bootloader = ..\..\tools\sdk\esp32s3\bin\bootloader_qio_120m.elf
board_upload.flash_size = 32MB
build_type = release

And while building:

Building in release mode
Compiling .pio/build/latest_stable/src/main.cpp.o
Building .pio/build/latest_stable/bootloader.bin
Generating partitions .pio/build/latest_stable/partitions.bin
usage: esptool elf2image [-h] [--output OUTPUT] [--version {1,2,3}]
                         [--min-rev-full {0, ... 65535}]
                         [--max-rev-full {0, ... 65535}] [--secure-pad]
                         [--secure-pad-v2]
                         [--elf-sha256-offset ELF_SHA256_OFFSET]
                         [--dont-append-digest] [--use_segments]
                         [--flash-mmu-page-size {64KB,32KB,16KB,8KB}]
                         [--pad-to-size PAD_TO_SIZE]
                         [--flash_freq {80m,60m,48m,40m,30m,26m,24m,20m,16m,15m,12m}]
                         [--flash_mode {qio,qout,dio,dout}]
                         [--flash_size {256KB,512KB,1MB,2MB,2MB-c1,4MB,4MB-c1,8MB,16MB,32MB,64MB,128MB}]
                         [--spi-connection SPI_CONNECTION]
                         input
esptool elf2image: error: argument --flash_freq/-ff: invalid choice: '120m' (choose from '80m', '60m', '48m', '40m', '30m', '26m', '24m', '20m', '16m', '15m', '12m')
Compiling .pio/build/latest_stable/lib005/FS/FS.cpp.o
*** [.pio/build/latest_stable/bootloader.bin] Error 2

It looks like f_flash frequency is only for flashing process.

In platform.txt you can find this:
build.img_freq={build.flash_freq}
build.boot=qio
build.boot_freq={build.flash_freq}

Try to play with boot_freq or img_freq.

I’ve been trying to make this work with your suggestions but still no luck.

So my .ini looks like this:

[env:esp32-s3-devkitc-1]
platform = espressif32
framework = arduino
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
board_build.arduino.memory_type = opi_opi ;"qio_qspi"
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = lib/file_system/custom32MB_partition.csv
board_build.arduino.custom_bootloader = ..\..\tools\sdk\esp32s3\bin\bootloader_qio_120m.elf

build.img_freq=80000000L
build.boot=qio
build.boot_freq=80000000L

board_upload.flash_size = 32MB
build_type = release
lib_ldf_mode = chain+
build_src_filter = +<../src/>
    -<../lib/**/main.cpp>
    +<../lib/>
    -<../**/examples/>
    -<.git/> 
    -<.svn/>

And when i try to build I get warnings:

Warning! Ignore unknown configuration option `build.img_freq` in section [env:esp32-s3-devkitc-1]
Warning! Ignore unknown configuration option `build.boot` in section [env:esp32-s3-devkitc-1]
Warning! Ignore unknown configuration option `build.boot_freq` in section [env:esp32-s3-devkitc-1]

The test code works same regardless these settings. I tried setting both build.img_freq and build.boot_freq to 120000000L and 40000000L etc. I’m testing the Flash read / write speed.

Try
board_build.boot_freq=

Ok, I’ve modified my .ini file to look like this:

[env:esp32-s3-devkitc-1]
platform = espressif32
framework = arduino
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
board_build.arduino.memory_type = opi_opi ;"qio_qspi"
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = lib/file_system/custom32MB_partition.csv
board_build.arduino.custom_bootloader = ..\..\tools\sdk\esp32s3\bin\bootloader_qio_120m.elf

;build.img_freq=80000000L
;build.boot=qio
;build.boot_freq=80000000L
board_build.boot_freq=140000000L

board_upload.flash_size = 32MB
build_type = release
lib_ldf_mode = chain+
build_src_filter = +<../src/>
    -<../lib/**/main.cpp>
    +<../lib/>
    -<../**/examples/>
    -<.git/> 
    -<.svn/>

The resaults I got i guess are within the error of measurement. It seems that this setting has no real effect on the read / write flash speed:

  1. board_build.boot_freq=120000000L
21:08:04.050 > Write Speed: 2841.84 KB/s
21:08:22.214 > Read Speed: 5637.52 KB/s
  1. board_build.boot_freq=80000000L
21:10:10.732 > Write Speed: 2863.45 KB/s
21:10:29.434 > Read Speed: 5475.35 KB/s
  1. board_build.boot_freq=140000000L
21:14:47.698 > Write Speed: 2843.58 KB/s
21:15:04.881 > Read Speed: 5959.38 KB/s
  1. board_build.boot_freq=1200000000L
21:16:43.213 > Write Speed: 2943.80 KB/s
21:17:01.370 > Read Speed: 5639.70 KB/s
  1. board_build.boot_freq=12000000000L
21:19:48.713 > Write Speed: 2832.25 KB/s
21:20:06.475 > Read Speed: 5764.79 KB/s
  1. I’ve commented out this settings both board_build.arduino.custom_bootloader and board_build.boot_freq out of the .ini file. And I received:
21:22:12.987 > Write Speed: 2884.18 KB/s
21:22:31.450 > Read Speed: 5546.23 KB/s

Like I mentioned earlier i guess these results prove that the setting isn’t quite there.

The code that i’m using is:

main.cpp:

#include <LittleFS.h>

const int fileSize = 1024; // 1 KB file size
const int numFiles = 100;  // Number of files to write
const char* filenamePrefix = "/file";



void writeFile(int index) {
  String filename = String(filenamePrefix) + String(index);
  File file = LittleFS.open(filename, "w");
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  for (int i = 0; i < fileSize; i++) {
    file.write(random(256)); // Write random data
  }
  file.close();
}

void readFile(int index) {
  String filename = String(filenamePrefix) + String(index);
  File file = LittleFS.open(filename, "r");
  if (!file) {
    Serial.println("Failed to open file for reading");
    return;
  }
  while (file.available()) {
    file.read(); // Reading but not storing data
  }
  file.close();
}



void setup() {
  Serial.begin(115200);

  if (!LittleFS.begin()) {
    Serial.println("LittleFS initialization failed!");
    return;
  }

  // Write files
  unsigned long startTime = millis();
  for (int i = 0; i < numFiles; i++) {
    writeFile(i);
  }
  unsigned long endTime = millis();
  
  unsigned long writeTime = endTime - startTime;
  float writeSpeed = (fileSize * numFiles) / ((float)writeTime / 1000); // in KB/s
  Serial.print("Write Speed: ");
  Serial.print(writeSpeed);
  Serial.println(" KB/s");

  // Read files
  startTime = millis();
  for (int i = 0; i < numFiles; i++) {
    readFile(i);
  }
  endTime = millis();
  
  unsigned long readTime = endTime - startTime;
  float readSpeed = (fileSize * numFiles) / ((float)readTime / 1000); // in KB/s
  Serial.print("Read Speed: ");
  Serial.print(readSpeed);
  Serial.println(" KB/s");
}

void loop() {
  // Nothing in loop for this example
}

So i thought that maybe the size of the file tested for read/write operations is too small so i changed:

const int fileSize = 3072000;
const int numFiles = 5;

The partitioning that i gives me 21.5 MB to play with.

Results for:

  1. “Default”:
[env:esp32-s3-devkitc-1]
platform = espressif32
framework = arduino
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
board_build.arduino.memory_type = opi_opi ;"qio_qspi"
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = lib/file_system/custom32MB_partition.csv
; board_build.arduino.custom_bootloader = ..\..\tools\sdk\esp32s3\bin\bootloader_qio_120m.elf

; build.img_freq=80000000L
; build.boot=qio
;build.boot_freq=80000000L
; board_build.boot_freq=80000000L

board_upload.flash_size = 32MB
build_type = release
lib_ldf_mode = chain+
build_src_filter = +<../src/>
    -<../lib/**/main.cpp>
    +<../lib/>
    -<../**/examples/>
    -<.git/> 
    -<.svn/>

Results:

21:52:24.293 > Write Speed: 32761.78 KB/s
21:56:29.803 > Read Speed: 62563.90 KB/s
  1. “bootloader_qio_120m.elf”:
[env:esp32-s3-devkitc-1]
platform = espressif32
framework = arduino
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
board_build.arduino.memory_type = opi_opi ;"qio_qspi"
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = lib/file_system/custom32MB_partition.csv
board_build.arduino.custom_bootloader = ..\..\tools\sdk\esp32s3\bin\bootloader_qio_120m.elf

; build.img_freq=80000000L
; build.boot=qio
;build.boot_freq=80000000L
board_build.boot_freq=120000000L

board_upload.flash_size = 32MB
build_type = release
lib_ldf_mode = chain+
build_src_filter = +<../src/>
    -<../lib/**/main.cpp>
    +<../lib/>
    -<../**/examples/>
    -<.git/> 
    -<.svn/>

Results:

22:07:12.021 > Write Speed: 32508.76 KB/s
22:11:17.460 > Read Speed: 62581.48 KB/s

As you can see the results are pretty much the same.

Only a bootloader which does support the switching to 120Mhz will not change anything.
The corresponding relevant precompiled Arduino libs needs to have the relevant code.
So it needs a custom compiled Arduino framework for this.
Edit: Mode QIO 120Mhz is included in Arduino framework build.
Looking through Platformio Platform espressif32 code, there is no option to set the 120Mhz.

Hello @jason2866 do you know how can i precompile arduino libs to get the 120Mhz flash functionality or somehow copy it over to platforio?

Is it even possible for a person like me to do so or do I have to have something?

I am currently doing this. The Platformio Framework should be done. But the 120Mhz support is not correct implemented in ArduinoIDE. So i currently can not implement the needed changes in my Platformio fork. I simply just don’t know what needs to be changed.

The compiled framework which has all needed compiled in is here
https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2156/framework-arduinoespressif32-release_v5.1-1a0b6e0.zip

1 Like

120Mhz builds should work now. My PRs for the missing code in Arduino and Platformio have been merged. Built a platform. You can try with platform = https://github.com/Jason2866/platform-espressif32.git
An example boards json for 120Mhz is in folder boards.
Blink example has an entry to build with 120Mhz

1 Like

Thank you @jason2866 I’ll try this out this weekend and do some read/write flash speed tests with these setting and compare!