/* * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 *//* ... */#include<stdlib.h>#include<assert.h>#include<string.h>#include<stdio.h>#include<sys/param.h>// For MIN/MAX(a, b)#include<freertos/FreeRTOS.h>#include<freertos/task.h>#include<freertos/semphr.h>#include<soc/soc.h>#include<soc/soc_memory_layout.h>#include"soc/io_mux_reg.h"#include"sdkconfig.h"#include"esp_attr.h"#include"esp_cpu.h"#include"spi_flash_mmap.h"#include"esp_log.h"#include"esp_private/system_internal.h"#include"esp_private/spi_flash_os.h"#include"esp_private/esp_clk.h"#include"esp_private/esp_gpio_reserve.h"20 includes#ifCONFIG_IDF_TARGET_ESP32#include"esp32/rom/cache.h"#include"esp32/rom/spi_flash.h"/* ... */#elifCONFIG_IDF_TARGET_ESP32S2#include"esp32s2/rom/cache.h"#elifCONFIG_IDF_TARGET_ESP32S3#include"soc/spi_mem_reg.h"#include"esp32s3/rom/opi_flash.h"#include"esp32s3/rom/cache.h"#include"esp32s3/opi_flash_private.h"/* ... */#elifCONFIG_IDF_TARGET_ESP32C3#include"esp32c3/rom/cache.h"#elifCONFIG_IDF_TARGET_ESP32C2#include"esp32c2/rom/cache.h"#elifCONFIG_IDF_TARGET_ESP32C6#include"esp32c6/rom/cache.h"#elifCONFIG_IDF_TARGET_ESP32C61#include"esp32c61/rom/cache.h"#endif#include"esp_rom_spiflash.h"#include"esp_flash_partitions.h"#include"esp_private/mspi_timing_tuning.h"#include"esp_private/cache_utils.h"#include"esp_flash.h"#include"esp_attr.h"#include"bootloader_flash.h"#include"bootloader_flash_config.h"#include"esp_compiler.h"#include"esp_rom_efuse.h"#include"soc/chip_revision.h"#include"hal/efuse_hal.h"12 includes#ifCONFIG_SPIRAM#include"esp_private/esp_psram_io.h"#endif#ifSOC_MEMSPI_CLOCK_IS_INDEPENDENT#include"hal/cache_hal.h"#endif/* bytes erased by SPIEraseBlock() ROM function */#defineBLOCK_ERASE_SIZE65536/* Limit number of bytes written/read in a single SPI operation, as these operations disable all higher priority tasks from running.*//* ... */#ifdefCONFIG_SPI_FLASH_WRITE_CHUNK_SIZE#defineMAX_WRITE_CHUNKCONFIG_SPI_FLASH_WRITE_CHUNK_SIZE#else#defineMAX_WRITE_CHUNK8192#endif// CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE#defineMAX_READ_CHUNK16384staticconstchar*TAG__attribute__((unused))="spi_flash";constDRAM_ATTRspi_flash_guard_funcs_tg_flash_guard_default_ops={.start=spi_flash_disable_interrupts_caches_and_other_cpu,.end=spi_flash_enable_interrupts_caches_and_other_cpu,}{...};constDRAM_ATTRspi_flash_guard_funcs_tg_flash_guard_no_os_ops={.start=spi_flash_disable_interrupts_caches_and_other_cpu_no_os,.end=spi_flash_enable_interrupts_caches_no_os,}{...};staticconstspi_flash_guard_funcs_t*s_flash_guard_ops;voidIRAM_ATTRspi_flash_guard_set(constspi_flash_guard_funcs_t*funcs){s_flash_guard_ops=funcs;}{ ... }constspi_flash_guard_funcs_t*IRAM_ATTRspi_flash_guard_get(void){returns_flash_guard_ops;}{ ... }#ifdefCONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS#defineUNSAFE_WRITE_ADDRESSabort()#else#defineUNSAFE_WRITE_ADDRESSreturnfalse#endifstatic__attribute__((unused))boolis_safe_write_address(size_taddr,size_tsize){if(!esp_partition_main_flash_region_safe(addr,size)){UNSAFE_WRITE_ADDRESS;}{...}returntrue;}{ ... }#ifCONFIG_SPI_FLASH_ROM_IMPL#include"esp_heap_caps.h"voidIRAM_ATTR*spi_flash_malloc_internal(size_tsize){returnheap_caps_malloc(size,MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);}{...}voidIRAM_ATTRspi_flash_rom_impl_init(void){spi_flash_guard_set(&g_flash_guard_default_ops);/* These two functions are in ROM only */externvoidspi_flash_mmap_os_func_set(void*(*func1)(size_tsize),void(*func2)(void*p));spi_flash_mmap_os_func_set(spi_flash_malloc_internal,heap_caps_free);externesp_err_tspi_flash_mmap_page_num_init(uint32_tpage_num);spi_flash_mmap_page_num_init(128);}{...}/* ... */#endifvoidIRAM_ATTResp_mspi_pin_init(void){#ifSOC_SPI_MEM_SUPPORT_OPI_MODEbooloctal_mspi_required=bootloader_flash_is_octal_mode_enabled();#ifCONFIG_SPIRAM_MODE_OCToctal_mspi_required|=true;#endifif(octal_mspi_required){esp_rom_opiflash_pin_config();mspi_timing_set_pin_drive_strength();}{...}//Set F4R4 board pin drive strength. TODO: IDF-3663/* ... */#endif}{ ... }voidesp_mspi_pin_reserve(void){uint64_treserve_pin_mask=0;uint8_tmspi_io;for(esp_mspi_io_ti=0;i<ESP_MSPI_IO_MAX;i++){#ifSOC_SPI_MEM_SUPPORT_OPI_MODEif(!bootloader_flash_is_octal_mode_enabled()&&i>=ESP_MSPI_IO_DQS&&i<=ESP_MSPI_IO_D7){continue;}{...}#endif/* ... */mspi_io=esp_mspi_get_io(i);if(mspi_io<64){// 'reserve_pin_mask' have 64 bits lengthreserve_pin_mask|=BIT64(mspi_io);}{...}}{...}esp_gpio_reserve(reserve_pin_mask);}{ ... }esp_err_tIRAM_ATTRspi_flash_init_chip_state(void){#ifSOC_SPI_MEM_SUPPORT_OPI_MODEif(bootloader_flash_is_octal_mode_enabled()){returnesp_opiflash_init(rom_spiflash_legacy_data->chip.device_id);}{...}#endif/* ... */#ifCONFIG_SPI_FLASH_HPM_ONreturnspi_flash_enable_high_performance_mode();#endif// CONFIG_SPI_FLASH_HPM_ONreturnESP_OK;}{ ... }voidIRAM_ATTRspi_flash_set_rom_required_regs(void){#ifSOC_SPI_MEM_SUPPORT_OPI_MODEif(bootloader_flash_is_octal_mode_enabled()){//Disable the variable dummy mode when doing timing tuningCLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1),SPI_MEM_SPI_FMEM_VAR_DUMMY);/** * STR /DTR mode setting is done every time when `esp_rom_opiflash_exec_cmd` is called * * Add any registers that are not set in ROM SPI flash functions here in the future *//* ... */}{...}#endif/* ... */}{ ... }#ifCONFIG_SPIRAM_MODE_OCT// This function will only be called when Octal PSRAM enabled.voidIRAM_ATTRspi_flash_set_vendor_required_regs(void){if(bootloader_flash_is_octal_mode_enabled()){esp_opiflash_set_required_regs();SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1),SPI_MEM_CACHE_USR_CMD_4BYTE_V,1,SPI_MEM_CACHE_USR_CMD_4BYTE_S);}{...}else{//Flash chip requires MSPI specifically, call this function to set them// Set back MSPI registers after Octal PSRAM initialization.SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1),SPI_MEM_CACHE_USR_CMD_4BYTE_V,0,SPI_MEM_CACHE_USR_CMD_4BYTE_S);}{...}}{...}/* ... */#endifstaticconstuint8_ts_mspi_io_num_default[]={MSPI_IOMUX_PIN_NUM_CLK,MSPI_IOMUX_PIN_NUM_MISO,MSPI_IOMUX_PIN_NUM_MOSI,MSPI_IOMUX_PIN_NUM_CS0,MSPI_IOMUX_PIN_NUM_HD,MSPI_IOMUX_PIN_NUM_WP,#ifSOC_SPI_MEM_SUPPORT_OPI_MODEMSPI_IOMUX_PIN_NUM_DQS,MSPI_IOMUX_PIN_NUM_D4,MSPI_IOMUX_PIN_NUM_D5,MSPI_IOMUX_PIN_NUM_D6,MSPI_IOMUX_PIN_NUM_D7/* ... */#endif// SOC_SPI_MEM_SUPPORT_OPI_MODE}{...};uint8_tesp_mspi_get_io(esp_mspi_io_tio){#ifCONFIG_SPIRAMif(io==ESP_MSPI_IO_CS1){returnesp_psram_io_get_cs_io();}{...}#endif/* ... */assert(io>=ESP_MSPI_IO_CLK);#ifSOC_SPI_MEM_SUPPORT_OPI_MODEassert(io<=ESP_MSPI_IO_D7);#elseassert(io<=ESP_MSPI_IO_WP);#endif#ifSOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSEuint8_tmspi_io=0;uint32_tspiconfig=0;if(io==ESP_MSPI_IO_WP){/** * wp pad is a bit special: * 1. since 32's efuse does not have enough bits for wp pad, so wp pad config put in flash bin header * 2. rom code take 0x3f as invalid wp pad num, but take 0 as other invalid mspi pads num *//* ... */#ifCONFIG_IDF_TARGET_ESP32returnbootloader_flash_get_wp_pin();#elsespiconfig=esp_rom_efuse_get_flash_wp_gpio();return(spiconfig==0x3f)?s_mspi_io_num_default[io]:spiconfig&0x3f;/* ... */#endif}{...}#ifSOC_SPI_MEM_SUPPORT_OPI_MODEspiconfig=(io<ESP_MSPI_IO_WP)?esp_rom_efuse_get_flash_gpio_info():esp_rom_efuse_get_opiconfig();#elsespiconfig=esp_rom_efuse_get_flash_gpio_info();#endif// SOC_SPI_MEM_SUPPORT_OPI_MODEif(spiconfig==ESP_ROM_EFUSE_FLASH_DEFAULT_SPI){mspi_io=s_mspi_io_num_default[io];}{...}elseif(io<ESP_MSPI_IO_WP){/** * [0 : 5] -- CLK * [6 :11] -- Q(D1) * [12:17] -- D(D0) * [18:23] -- CS * [24:29] -- HD(D3) *//* ... */mspi_io=(spiconfig>>io*6)&0x3f;}{...}#ifSOC_SPI_MEM_SUPPORT_OPI_MODEelse{/** * [0 : 5] -- DQS * [6 :11] -- D4 * [12:17] -- D5 * [18:23] -- D6 * [24:29] -- D7 *//* ... */mspi_io=(spiconfig>>(io-ESP_MSPI_IO_DQS)*6)&0x3f;}{...}#endif/* ... */// SOC_SPI_MEM_SUPPORT_OPI_MODEreturnmspi_io;/* ... */#else// SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSEreturns_mspi_io_num_default[io];#endif// SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE}{ ... }#if!CONFIG_IDF_TARGET_ESP32P4||!CONFIG_APP_BUILD_TYPE_RAM// IDF-10019esp_err_tIRAM_ATTResp_mspi_32bit_address_flash_feature_check(void){#ifCONFIG_IDF_TARGET_ESP32C6||CONFIG_IDF_TARGET_ESP32H2ESP_EARLY_LOGE(TAG,"32bit address (flash over 16MB) has high risk on this chip");returnESP_ERR_NOT_SUPPORTED;/* ... */#elifCONFIG_IDF_TARGET_ESP32P4// IDF-10019unsignedchip_version=efuse_hal_chip_revision();if(unlikely(!ESP_CHIP_REV_ABOVE(chip_version,1))){ESP_EARLY_LOGE(TAG,"32bit address (flash over 16MB) has high risk on ESP32P4 ECO0");returnESP_ERR_NOT_SUPPORTED;}{...}#endif/* ... */returnESP_OK;}{ ... }/* ... */#endif// !CONFIG_IDF_TARGET_ESP32P4 || !CONFIG_APP_BUILD_TYPE_RAM
Details
Show: from
Types: Columns:
All items filtered out
All items filtered out
This file uses the notable symbols shown below. Click anywhere in the file to view more details.