esp_flash: add support mxic as a main flash under spi mode

This commit is contained in:
Cao Sen Miao 2021-06-29 15:32:50 +08:00
parent d5f58ab135
commit 559c1ac3f9
7 changed files with 95 additions and 12 deletions

View File

@ -91,6 +91,7 @@ menu "Serial flasher config"
choice ESPTOOLPY_FLASHMODE choice ESPTOOLPY_FLASHMODE
prompt "Flash SPI mode" prompt "Flash SPI mode"
default ESPTOOLPY_FLASHMODE_DIO default ESPTOOLPY_FLASHMODE_DIO
depends on !ESPTOOLPY_OCT_FLASH
help help
Mode the flash chip is flashed in, as well as the default mode for the Mode the flash chip is flashed in, as well as the default mode for the
binary to run in. binary to run in.
@ -103,6 +104,10 @@ menu "Serial flasher config"
bool "DIO" bool "DIO"
config ESPTOOLPY_FLASHMODE_DOUT config ESPTOOLPY_FLASHMODE_DOUT
bool "DOUT" bool "DOUT"
config ESPTOOLPY_FLASHMODE_FASTRD
bool "FASTRD"
config ESPTOOLPY_FLASHMODE_SLOWRD
bool "SLOWRD"
endchoice endchoice
# Note: we use esptool.py to flash bootloader in # Note: we use esptool.py to flash bootloader in
@ -114,6 +119,10 @@ menu "Serial flasher config"
default "dio" if ESPTOOLPY_FLASHMODE_QOUT default "dio" if ESPTOOLPY_FLASHMODE_QOUT
default "dio" if ESPTOOLPY_FLASHMODE_DIO default "dio" if ESPTOOLPY_FLASHMODE_DIO
default "dout" if ESPTOOLPY_FLASHMODE_DOUT default "dout" if ESPTOOLPY_FLASHMODE_DOUT
default "dout" if ESPTOOLPY_FLASHMODE_FASTRD
default "dout" if ESPTOOLPY_FLASHMODE_SLOWRD
default "dout" if ESPTOOLPY_FLASHMODE_OPI_STR
default "dout" if ESPTOOLPY_FLASHMODE_OPI_DTR
choice ESPTOOLPY_FLASHFREQ choice ESPTOOLPY_FLASHFREQ
prompt "Flash SPI speed" prompt "Flash SPI speed"

View File

@ -68,6 +68,10 @@ esp_flash_t *esp_flash_default_chip = NULL;
#define DEFAULT_FLASH_MODE SPI_FLASH_DIO #define DEFAULT_FLASH_MODE SPI_FLASH_DIO
#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DOUT) #elif defined(CONFIG_ESPTOOLPY_FLASHMODE_DOUT)
#define DEFAULT_FLASH_MODE SPI_FLASH_DOUT #define DEFAULT_FLASH_MODE SPI_FLASH_DOUT
#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_FASTRD)
#define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD
#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_SLOWRD)
#define DEFAULT_FLASH_MODE SPI_FLASH_SLOWRD
#else #else
#define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD #define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD
#endif #endif

View File

@ -518,6 +518,7 @@ out:
#endif // CONFIG_SPI_FLASH_USE_LEGACY_IMPL #endif // CONFIG_SPI_FLASH_USE_LEGACY_IMPL
#if !CONFIG_SPI_FLASH_USE_LEGACY_IMPL #if !CONFIG_SPI_FLASH_USE_LEGACY_IMPL
#if !CONFIG_ESPTOOLPY_OCT_FLASH
extern void spi_common_set_dummy_output(esp_rom_spiflash_read_mode_t mode); extern void spi_common_set_dummy_output(esp_rom_spiflash_read_mode_t mode);
extern void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv); extern void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
void IRAM_ATTR flash_rom_init(void) void IRAM_ATTR flash_rom_init(void)
@ -557,6 +558,10 @@ void IRAM_ATTR flash_rom_init(void)
read_mode = ESP_ROM_SPIFLASH_DIO_MODE; read_mode = ESP_ROM_SPIFLASH_DIO_MODE;
#elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT #elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT
read_mode = ESP_ROM_SPIFLASH_DOUT_MODE; read_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
#elif CONFIG_ESPTOOLPY_FLASHMODE_FASTRD
read_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
#elif CONFIG_ESPTOOLPY_FLASHMODE_SLOWRD
read_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE;
#endif #endif
#endif //!CONFIG_IDF_TARGET_ESP32S2 && !CONFIG_IDF_TARGET_ESP32 #endif //!CONFIG_IDF_TARGET_ESP32S2 && !CONFIG_IDF_TARGET_ESP32
@ -571,6 +576,7 @@ void IRAM_ATTR flash_rom_init(void)
#endif //!CONFIG_IDF_TARGET_ESP32S2 #endif //!CONFIG_IDF_TARGET_ESP32S2
esp_rom_spiflash_config_clk(freqdiv, 1); esp_rom_spiflash_config_clk(freqdiv, 1);
} }
#endif //CONFIG_ESPTOOLPY_OCT_FLASH
#else #else
void IRAM_ATTR flash_rom_init(void) void IRAM_ATTR flash_rom_init(void)
{ {

View File

@ -30,6 +30,15 @@ typedef struct {
uint32_t page_program_timeout; ///< Timeout for page program operation uint32_t page_program_timeout; ///< Timeout for page program operation
} flash_chip_op_timeout_t; } flash_chip_op_timeout_t;
typedef struct flash_chip_dummy {
uint8_t dio_dummy_bitlen;
uint8_t qio_dummy_bitlen;
uint8_t qout_dummy_bitlen;
uint8_t dout_dummy_bitlen;
uint8_t fastrd_dummy_bitlen;
uint8_t slowrd_dummy_bitlen;
} flash_chip_dummy_t;
typedef enum { typedef enum {
SPI_FLASH_REG_STATUS = 1, SPI_FLASH_REG_STATUS = 1,
} spi_flash_register_t; } spi_flash_register_t;

View File

@ -21,15 +21,6 @@
#include "esp_log.h" #include "esp_log.h"
#include "esp_attr.h" #include "esp_attr.h"
typedef struct flash_chip_dummy {
uint8_t dio_dummy_bitlen;
uint8_t qio_dummy_bitlen;
uint8_t qout_dummy_bitlen;
uint8_t dout_dummy_bitlen;
uint8_t fastrd_dummy_bitlen;
uint8_t slowrd_dummy_bitlen;
} flash_chip_dummy_t;
// These parameters can be placed in the ROM. For now we use the code in IDF. // These parameters can be placed in the ROM. For now we use the code in IDF.
DRAM_ATTR const static flash_chip_dummy_t default_flash_chip_dummy = { DRAM_ATTR const static flash_chip_dummy_t default_flash_chip_dummy = {
.dio_dummy_bitlen = SPI_FLASH_DIO_DUMMY_BITLEN, .dio_dummy_bitlen = SPI_FLASH_DIO_DUMMY_BITLEN,

View File

@ -16,9 +16,13 @@
#include "spi_flash_chip_generic.h" #include "spi_flash_chip_generic.h"
#include "spi_flash_defs.h" #include "spi_flash_defs.h"
#include "esp_log.h" #include "esp_log.h"
#include "string.h"
#include <sys/param.h> // For MIN/MAX
/* Driver for MXIC flash chip */ /* Driver for MXIC flash chip */
extern flash_chip_dummy_t *rom_flash_chip_dummy;
esp_err_t spi_flash_chip_mxic_probe(esp_flash_t *chip, uint32_t flash_id) esp_err_t spi_flash_chip_mxic_probe(esp_flash_t *chip, uint32_t flash_id)
{ {
/* Check manufacturer and product IDs match our desired masks */ /* Check manufacturer and product IDs match our desired masks */
@ -47,6 +51,43 @@ esp_err_t spi_flash_chip_mxic_read_unique_id(esp_flash_t *chip, uint64_t* flash_
return ESP_ERR_NOT_SUPPORTED; return ESP_ERR_NOT_SUPPORTED;
} }
esp_err_t spi_flash_chip_mxic_read(esp_flash_t *chip, void *buffer, uint32_t address, uint32_t length)
{
esp_err_t err = ESP_OK;
const uint32_t page_size = chip->chip_drv->page_size;
uint32_t align_address;
uint8_t temp_buffer[64]; //spiflash hal max length of read no longer than 64byte
// Configure the host, and return
uint32_t addr_bitlen = SPI_FLASH_FASTRD_ADDR_BITLEN;
uint32_t dummy_cyclelen_base = rom_flash_chip_dummy->fastrd_dummy_bitlen;;
uint32_t read_command = CMD_FASTRD;
uint32_t read_mode = SPI_FLASH_FASTRD;
err = chip->host->driver->configure_host_io_mode(chip->host, read_command, addr_bitlen, dummy_cyclelen_base, read_mode);
if (err == ESP_ERR_NOT_SUPPORTED) {
ESP_LOGE(chip_name, "configure host io mode failed - unsupported");
return err;
}
while (err == ESP_OK && length > 0) {
memset(temp_buffer, 0xFF, sizeof(temp_buffer));
uint32_t read_len = chip->host->driver->read_data_slicer(chip->host, address, length, &align_address, page_size);
uint32_t left_off = address - align_address;
uint32_t data_len = MIN(align_address + read_len, address + length) - address;
err = chip->host->driver->read(chip->host, temp_buffer, align_address, read_len);
memcpy(buffer, temp_buffer + left_off, data_len);
address += data_len;
buffer = (void *)((intptr_t)buffer + data_len);
length = length - data_len;
}
return err;
}
spi_flash_caps_t spi_flash_chip_mxic_get_caps(esp_flash_t *chip) spi_flash_caps_t spi_flash_chip_mxic_get_caps(esp_flash_t *chip)
{ {
spi_flash_caps_t caps_flags = 0; spi_flash_caps_t caps_flags = 0;

View File

@ -23,15 +23,25 @@
#include <unity.h> #include <unity.h>
#include <test_utils.h> #include <test_utils.h>
#include <esp_spi_flash.h> #include <esp_spi_flash.h>
#include <esp32/rom/spi_flash.h>
#include "../cache_utils.h" #include "../cache_utils.h"
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#if CONFIG_IDF_TARGET_ESP32
#include <esp32/rom/spi_flash.h>
#elif CONFIG_IDF_TARGET_ESP32S2
#include <esp32s2/rom/spi_flash.h>
#elif CONFIG_IDF_TARGET_ESP32S3
#include <esp32s3/rom/spi_flash.h>
#elif CONFIG_IDF_TARGET_ESP32C3
#include <esp32c3/rom/spi_flash.h>
#endif
#define MIN_BLOCK_SIZE 12 #define MIN_BLOCK_SIZE 12
/* Base offset in flash for tests. */ /* Base offset in flash for tests. */
static size_t start; static size_t start;
extern spiflash_legacy_data_t *rom_spiflash_legacy_data;
static void setup_tests(void) static void setup_tests(void)
{ {
@ -141,11 +151,13 @@ TEST_CASE("Test spi_flash_read", "[spi_flash][esp_flash]")
#endif #endif
} }
#if !CONFIG_ESPTOOLPY_OCT_FLASH
extern void spi_common_set_dummy_output(esp_rom_spiflash_read_mode_t mode); extern void spi_common_set_dummy_output(esp_rom_spiflash_read_mode_t mode);
extern void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv); extern void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
static void IRAM_ATTR fix_rom_func(void) static void IRAM_ATTR fix_rom_func(void)
{ {
uint32_t freqdiv = 0; uint32_t freqdiv = 0;
uint32_t vendor_id = (rom_spiflash_legacy_data->chip.device_id >> 16);
#if CONFIG_ESPTOOLPY_FLASHFREQ_80M #if CONFIG_ESPTOOLPY_FLASHFREQ_80M
freqdiv = 1; freqdiv = 1;
@ -182,14 +194,24 @@ static void IRAM_ATTR fix_rom_func(void)
read_mode = ESP_ROM_SPIFLASH_DIO_MODE; read_mode = ESP_ROM_SPIFLASH_DIO_MODE;
#elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT #elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT
read_mode = ESP_ROM_SPIFLASH_DOUT_MODE; read_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
#elif CONFIG_ESPTOOLPY_FLASHMODE_FASTRD
read_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
#elif CONFIG_ESPTOOLPY_FLASHMODE_SLOWRD
read_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE;
#endif #endif
#if !CONFIG_IDF_TARGET_ESP32S2 && !CONFIG_IDF_TARGET_ESP32 #if !CONFIG_IDF_TARGET_ESP32S2 && !CONFIG_IDF_TARGET_ESP32
spi_common_set_dummy_output(read_mode); spi_common_set_dummy_output(read_mode);
#endif //!CONFIG_IDF_TARGET_ESP32S2 #endif //!CONFIG_IDF_TARGET_ESP32S2
esp_rom_spiflash_config_clk(freqdiv, 1); esp_rom_spiflash_config_clk(freqdiv, 1);
esp_rom_spiflash_config_readmode(read_mode); if (vendor_id == 0xc2) {
// If the flash vendor is mxic, it dones't support the read mode mentioned above.
// So, do nothing
} else {
esp_rom_spiflash_config_readmode(read_mode);
}
} }
#endif
static void IRAM_ATTR test_write(int dst_off, int src_off, int len) static void IRAM_ATTR test_write(int dst_off, int src_off, int len)
{ {
@ -211,8 +233,9 @@ static void IRAM_ATTR test_write(int dst_off, int src_off, int len)
fill(dst_gold + dst_off, src_off, len); fill(dst_gold + dst_off, src_off, len);
} }
ESP_ERROR_CHECK(spi_flash_write(start + dst_off, src_buf + src_off, len)); ESP_ERROR_CHECK(spi_flash_write(start + dst_off, src_buf + src_off, len));
#if !CONFIG_ESPTOOLPY_OCT_FLASH
fix_rom_func(); fix_rom_func();
#endif
spi_flash_disable_interrupts_caches_and_other_cpu(); spi_flash_disable_interrupts_caches_and_other_cpu();
esp_rom_spiflash_result_t rc = esp_rom_spiflash_read(start, dst_buf, sizeof(dst_buf)); esp_rom_spiflash_result_t rc = esp_rom_spiflash_read(start, dst_buf, sizeof(dst_buf));