Functions for getting/setting the SPI flash frequency

PanicanWhyasker
Posts: 8
Joined: Sun Jan 06, 2019 12:42 pm

Functions for getting/setting the SPI flash frequency

Postby PanicanWhyasker » Sat Jan 12, 2019 8:45 am

Background
One of the promising suggestions I got in my other thread was to try lowering the flash frequency from 80 MHz to 40 MHz, which I would want to try ASAP, however the devices I want to try that on are on the field for testing - I can only OTA update them.

AFAIK the flash frequency can only be changed locally by setting the proper cmdline parameters to esptool and uploading a new bootloader for that flash speed as well. In fact, I tried recompiling for 40 MHz and OTA updated one device locally and it seems it didn't slow down the tiniest bit, but then again I'm not 100% sure and I want to verify what the flash speed is now. I looked around and I couldn't find functions to query that, hence this thread.

It seems that the flash speed is set in

Code: Select all

esp-idf/components/spi_flash/spi_flash_rom_patch.c
, specifically in

Code: Select all

spi_cache_mode_switch()
, which reads values from

Code: Select all

g_rom_spiflash_dummy_len_plus[]
, which in turn is set by flash_gpio_configure() in

Code: Select all

esp-idf/components/bootloader_support/src/bootloader_init.c
If my suspicion is correct, reading the flash speed is just fetching the values from SPI_USER1_REG(0) and SPI_USER2_REG(0), then decoding them (there would be a couple of magic constant pairs for these regs, one corresponds to 40 MHz, one to 80 MHz). Let's call this get_spi_flash_freq().

Then I'd also want to lower the SPI flash freq for my devices on the field - it might be doable by quickly changing both registers with the magics for 40 MHz (say we name this function set_spi_flash_freq()). I can OTA upload a new firmware that calls set_spi_flash_freq() in the beginning and my devices will run on 40MHz almost all the time.

Questions
1. Is there any code that already implements something similar the proposed get_spi_flash_freq()/set_spi_flash_freq() funcs described above?
2. Is the approach in set_spi_flash_freq() workable, can you do that with the flash already being actively used?

PanicanWhyasker
Posts: 8
Joined: Sun Jan 06, 2019 12:42 pm

Re: Functions for getting/setting the SPI flash frequency

Postby PanicanWhyasker » Mon Jan 14, 2019 1:07 pm

Any thoughts?

I implemented 1 and got:

80 MHz:

Code: Select all

SPI_USER1_REG(0) = 0x5c000005
SPI_USER2_REG(0) = 0x700000bb
g_rom_spiflash_dummy_len_plus[0] = g_rom_spiflash_dummy_len_plus[1] = 2
40 MHz:

Code: Select all

SPI_USER1_REG(0) = 0x5c000004
SPI_USER2_REG(0) = 0x700000bb
g_rom_spiflash_dummy_len_plus[0] = g_rom_spiflash_dummy_len_plus[1] = 1
I tried applying the settings for 40 MHz on a device that has 80 MHz programmed in the bootloader, but it crashes when I attempt to do it. I got this on the UART:

Code: Select all

Guru Meditation Error: Core  0 panic'ed (InstrFetchProhibited). Exception was unhandled.
Guru Meditation Error: Core  0 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x40150b7c: 0000007c 2740900d 3341ef40
Guru Meditation Error: Core  0 panic'ed (IllegalInstruction). Exception was unhandled.
... then a bunch more

Probably the flash settings can be changed only while the SPI flash is not in use, but who knows...
Any pointers?

Return to “ESP32 IDF”

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot], Google [Bot] and 9 guests