Page 1 of 1

Functions for getting/setting the SPI flash frequency

Posted: Sat Jan 12, 2019 8:45 am
by PanicanWhyasker
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?

Re: Functions for getting/setting the SPI flash frequency

Posted: Mon Jan 14, 2019 1:07 pm
by PanicanWhyasker
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?