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
prompt "Flash SPI mode"
default ESPTOOLPY_FLASHMODE_DIO
depends on !ESPTOOLPY_OCT_FLASH
help
Mode the flash chip is flashed in, as well as the default mode for the
binary to run in.
@ -103,6 +104,10 @@ menu "Serial flasher config"
bool "DIO"
config ESPTOOLPY_FLASHMODE_DOUT
bool "DOUT"
config ESPTOOLPY_FLASHMODE_FASTRD
bool "FASTRD"
config ESPTOOLPY_FLASHMODE_SLOWRD
bool "SLOWRD"
endchoice
# 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_DIO
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
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
#elif defined(CONFIG_ESPTOOLPY_FLASHMODE_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
#define DEFAULT_FLASH_MODE SPI_FLASH_FASTRD
#endif

View File

@ -518,6 +518,7 @@ out:
#endif // 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_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
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;
#elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT
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 //!CONFIG_IDF_TARGET_ESP32S2 && !CONFIG_IDF_TARGET_ESP32
@ -571,6 +576,7 @@ void IRAM_ATTR flash_rom_init(void)
#endif //!CONFIG_IDF_TARGET_ESP32S2
esp_rom_spiflash_config_clk(freqdiv, 1);
}
#endif //CONFIG_ESPTOOLPY_OCT_FLASH
#else
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
} 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 {
SPI_FLASH_REG_STATUS = 1,
} spi_flash_register_t;

View File

@ -21,15 +21,6 @@
#include "esp_log.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.
DRAM_ATTR const static flash_chip_dummy_t default_flash_chip_dummy = {
.dio_dummy_bitlen = SPI_FLASH_DIO_DUMMY_BITLEN,

View File

@ -16,9 +16,13 @@
#include "spi_flash_chip_generic.h"
#include "spi_flash_defs.h"
#include "esp_log.h"
#include "string.h"
#include <sys/param.h> // For MIN/MAX
/* 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)
{
/* 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;
}
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 caps_flags = 0;

View File

@ -23,15 +23,25 @@
#include <unity.h>
#include <test_utils.h>
#include <esp_spi_flash.h>
#include <esp32/rom/spi_flash.h>
#include "../cache_utils.h"
#include "soc/timer_periph.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
/* Base offset in flash for tests. */
static size_t start;
extern spiflash_legacy_data_t *rom_spiflash_legacy_data;
static void setup_tests(void)
{
@ -141,11 +151,13 @@ TEST_CASE("Test spi_flash_read", "[spi_flash][esp_flash]")
#endif
}
#if !CONFIG_ESPTOOLPY_OCT_FLASH
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);
static void IRAM_ATTR fix_rom_func(void)
{
uint32_t freqdiv = 0;
uint32_t vendor_id = (rom_spiflash_legacy_data->chip.device_id >> 16);
#if CONFIG_ESPTOOLPY_FLASHFREQ_80M
freqdiv = 1;
@ -182,14 +194,24 @@ static void IRAM_ATTR fix_rom_func(void)
read_mode = ESP_ROM_SPIFLASH_DIO_MODE;
#elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT
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
#if !CONFIG_IDF_TARGET_ESP32S2 && !CONFIG_IDF_TARGET_ESP32
spi_common_set_dummy_output(read_mode);
#endif //!CONFIG_IDF_TARGET_ESP32S2
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)
{
@ -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);
}
ESP_ERROR_CHECK(spi_flash_write(start + dst_off, src_buf + src_off, len));
#if !CONFIG_ESPTOOLPY_OCT_FLASH
fix_rom_func();
#endif
spi_flash_disable_interrupts_caches_and_other_cpu();
esp_rom_spiflash_result_t rc = esp_rom_spiflash_read(start, dst_buf, sizeof(dst_buf));