| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- /*
- * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include "sdkconfig.h"
- #include "esp_log.h"
- #include "esp_err.h"
- #include "esp_rom_gpio.h"
- #include "esp32s3/rom/gpio.h"
- #include "esp32s3/rom/spi_flash.h"
- #include "esp32s3/rom/opi_flash.h"
- #include "esp_private/spi_flash_os.h"
- #include "opi_flash_private.h"
- #include "soc/spi_mem_reg.h"
- #include "soc/io_mux_reg.h"
- #include "opi_flash_cmd_format_mxic.h"
- #define SPI_FLASH_SPI_CMD_WRCR2 0x72
- #define SPI_FLASH_SPI_CMD_RDSR 0x05
- #define SPI_FLASH_SPI_CMD_RDCR 0x15
- #define SPI_FLASH_SPI_CMD_WRSRCR 0x01
- /**
- * Supported Flash chip vendor id
- */
- #define ESP_FLASH_CHIP_MXIC_OCT 0xC2
- const static char *TAG = "Octal Flash";
- // default value is rom_default_spiflash_legacy_flash_func
- extern const spiflash_legacy_funcs_t *rom_spiflash_legacy_funcs;
- extern int SPI_write_enable(void *spi);
- static uint32_t s_vendor_id;
- static void s_register_rom_function(void)
- {
- static spiflash_legacy_funcs_t rom_func =
- {
- .read_sub_len = 32,
- .write_sub_len = 32,
- .unlock = esp_rom_opiflash_wait_idle,
- .erase_block = esp_rom_opiflash_erase_block_64k,
- .erase_sector = esp_rom_opiflash_erase_sector,
- .read = esp_rom_opiflash_read,
- .write = esp_rom_opiflash_write,
- .wait_idle = esp_rom_opiflash_wait_idle,
- .wren = esp_rom_opiflash_wren,
- .erase_area = esp_rom_opiflash_erase_area,
- };
- rom_spiflash_legacy_funcs = &rom_func;
- }
- #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
- /*----------------------------------------------------------------------------------------------------
- MXIC Specific Functions
- -----------------------------------------------------------------------------------------------------*/
- static esp_err_t s_probe_mxic_chip(uint32_t chip_id, uint8_t *out_vendor_id)
- {
- if (chip_id >> 16 != ESP_FLASH_CHIP_MXIC_OCT) {
- return ESP_ERR_NOT_FOUND;
- }
- if (((chip_id >> 8) & 0xff) != 0x80) {
- ESP_EARLY_LOGE(TAG, "Detected MXIC Flash, but memory type is not Octal");
- return ESP_ERR_NOT_FOUND;
- }
- *out_vendor_id = ESP_FLASH_CHIP_MXIC_OCT;
- return ESP_OK;
- }
- // 0x00: SPI; 0x01: STR OPI; 0x02: DTR OPI
- static void s_set_flash_dtr_str_opi_mode(int spi_num, uint8_t val)
- {
- uint8_t cmd_len = 8;
- int addr_bit_len = 32;
- int dummy = 0;
- int data_bit_len = 8;
- SPI_write_enable(&g_rom_flashchip);
- //SPI command, WRCR2
- esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
- SPI_FLASH_SPI_CMD_WRCR2, cmd_len,
- 0, addr_bit_len,
- dummy,
- (uint8_t *)&val, data_bit_len,
- NULL, 0,
- ESP_ROM_OPIFLASH_SEL_CS0,
- false);
- }
- //To set the output driver strength
- static void s_set_flash_ouput_driver_strength(int spi_num, uint8_t strength)
- {
- uint16_t reg_val = 0;
- uint8_t sr_reg_val = 0;
- uint8_t cr_reg_val = 0;
- uint8_t cmd_len = 8;
- uint32_t addr = 0;
- int addr_bit_len = 0;
- int dummy = 0;
- int data_bit_len = 8;
- //Read
- //SPI command, RDSR
- esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
- SPI_FLASH_SPI_CMD_RDSR, cmd_len,
- addr, addr_bit_len,
- dummy,
- NULL, 0,
- (uint8_t*)&sr_reg_val, data_bit_len,
- ESP_ROM_OPIFLASH_SEL_CS0,
- false);
- //SPI command, RDCR
- esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
- SPI_FLASH_SPI_CMD_RDCR, cmd_len,
- addr, addr_bit_len,
- dummy,
- NULL, 0,
- (uint8_t*)&cr_reg_val, data_bit_len,
- ESP_ROM_OPIFLASH_SEL_CS0,
- false);
- //Modify
- reg_val = (((cr_reg_val & 0xf8) | strength) << 8) | sr_reg_val;
- //Write
- //SPI command, WRSR/WRCR
- data_bit_len = 16;
- SPI_write_enable(&g_rom_flashchip);
- esp_rom_opiflash_exec_cmd(spi_num, ESP_ROM_SPIFLASH_FASTRD_MODE,
- SPI_FLASH_SPI_CMD_WRSRCR, cmd_len,
- addr, addr_bit_len,
- dummy,
- (uint8_t*)®_val, data_bit_len,
- NULL, 0,
- ESP_ROM_OPIFLASH_SEL_CS0,
- false);
- }
- static void s_set_pin_drive_capability(uint8_t drv)
- {
- //flash clock
- REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV, 3);
- //cs0
- PIN_SET_DRV(IO_MUX_GPIO29_REG, 3);
- }
- static void s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode)
- {
- static const esp_rom_opiflash_def_t opiflash_cmd_def_mxic = OPI_CMD_FORMAT_MXIC();
- esp_rom_opiflash_legacy_driver_init(&opiflash_cmd_def_mxic);
- esp_rom_spiflash_wait_idle(&g_rom_flashchip);
- // increase flash output driver strength
- s_set_flash_ouput_driver_strength(1, 7);
- // STR/DTR specific setting
- esp_rom_spiflash_wait_idle(&g_rom_flashchip);
- #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR
- s_set_pin_drive_capability(3);
- s_set_flash_dtr_str_opi_mode(1, 0x1);
- esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd);
- esp_rom_spi_set_dtr_swap_mode(0, false, false);
- esp_rom_spi_set_dtr_swap_mode(1, false, false);
- #else //CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
- s_set_pin_drive_capability(3);
- s_set_flash_dtr_str_opi_mode(1, 0x2);
- esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd);
- esp_rom_spi_set_dtr_swap_mode(0, true, true);
- esp_rom_spi_set_dtr_swap_mode(1, true, true);
- #endif
- esp_rom_opiflash_wait_idle();
- }
- #endif // #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
- /*----------------------------------------------------------------------------------------------------
- General Functions
- -----------------------------------------------------------------------------------------------------*/
- typedef struct opi_flash_func_t {
- esp_err_t (*probe)(uint32_t flash_id, uint8_t *out_vendor_id); //Function pointer for detecting Flash chip vendor
- void (*init)(esp_rom_spiflash_read_mode_t mode); //Function pointer for initialising certain Flash chips
- } opi_flash_func_t;
- #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
- static const opi_flash_func_t opi_flash_func_mxic = {
- .probe = &s_probe_mxic_chip,
- .init = &s_flash_init_mxic
- };
- #endif
- static const opi_flash_func_t *registered_chip_funcs[] = {
- #if CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP
- &opi_flash_func_mxic,
- #endif
- NULL,
- };
- esp_err_t esp_opiflash_init(uint32_t chip_id)
- {
- esp_err_t ret = ESP_FAIL;
- esp_rom_spiflash_read_mode_t mode;
- #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR
- mode = ESP_ROM_SPIFLASH_OPI_STR_MODE;
- #elif CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
- mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE;
- #else
- mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
- #endif
- //To check which Flash chip is used
- const opi_flash_func_t **chip_func = ®istered_chip_funcs[0];
- uint8_t vendor_id = 0;
- while (*chip_func) {
- ret = (*chip_func)->probe(chip_id, &vendor_id);
- if (ret == ESP_OK) {
- // Detect this is the supported chip type
- (*chip_func)->init(mode);
- s_vendor_id = vendor_id;
- s_register_rom_function();
- break;
- }
- chip_func++;
- }
- if (ret != ESP_OK) {
- ESP_EARLY_LOGE(TAG, "No detected Flash chip, please check the menuconfig to see if the chip is supported");
- abort();
- }
- return ESP_OK;
- }
- /**
- * Add Flash chip specifically required MSPI register settings here
- */
- void esp_opiflash_set_required_regs(void)
- {
- bool is_swap = false;
- #if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
- if (s_vendor_id == ESP_FLASH_CHIP_MXIC_OCT) {
- is_swap = true;
- }
- #else
- //STR mode does not need to enable ddr_swap registers
- #endif
- esp_rom_spi_set_dtr_swap_mode(0, is_swap, is_swap);
- esp_rom_spi_set_dtr_swap_mode(1, is_swap, is_swap);
- }
|