mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-20 00:36:01 -04:00
esp_flash: add support mxic as a main flash under spi mode
This commit is contained in:
parent
d5f58ab135
commit
559c1ac3f9
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
Loading…
Reference in New Issue
Block a user