mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
spi_flash: Making XMC flash works more stable when brownout detected
This commit is contained in:
parent
890f046ee9
commit
6a2d3509dc
@ -49,6 +49,12 @@ esp_err_t bootloader_flash_xmc_startup(void);
|
||||
*/
|
||||
esp_err_t __attribute__((weak)) bootloader_flash_unlock(void);
|
||||
|
||||
/**
|
||||
* @brief Reset the flash chip (66H + 99H).
|
||||
*
|
||||
* @return ESP_OK if success, otherwise ESP_FAIL.
|
||||
*/
|
||||
esp_err_t bootloader_flash_reset_chip(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -730,3 +730,44 @@ esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void)
|
||||
}
|
||||
|
||||
#endif //XMC_SUPPORT
|
||||
|
||||
FORCE_INLINE_ATTR void bootloader_mspi_reset(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SPI1.slave.sync_reset = 0;
|
||||
SPI0.slave.sync_reset = 0;
|
||||
SPI1.slave.sync_reset = 1;
|
||||
SPI0.slave.sync_reset = 1;
|
||||
SPI1.slave.sync_reset = 0;
|
||||
SPI0.slave.sync_reset = 0;
|
||||
#else
|
||||
SPIMEM1.ctrl2.sync_reset = 0;
|
||||
SPIMEM0.ctrl2.sync_reset = 0;
|
||||
SPIMEM1.ctrl2.sync_reset = 1;
|
||||
SPIMEM0.ctrl2.sync_reset = 1;
|
||||
SPIMEM1.ctrl2.sync_reset = 0;
|
||||
SPIMEM0.ctrl2.sync_reset = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR bootloader_flash_reset_chip(void)
|
||||
{
|
||||
bootloader_mspi_reset();
|
||||
// Seems that sync_reset cannot make host totally idle.'
|
||||
// Sending an extra(useless) command to make the host idle in order to send reset command.
|
||||
bootloader_execute_flash_command(0x05, 0, 0, 0);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (SPI1.ext2.st != 0)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
if (SPIMEM1.fsm.st != 0)
|
||||
#else
|
||||
if (SPIMEM1.fsm.spi0_mst_st != 0)
|
||||
#endif
|
||||
{
|
||||
return ESP_FAIL;
|
||||
}
|
||||
bootloader_execute_flash_command(0x66, 0, 0, 0);
|
||||
bootloader_execute_flash_command(0x99, 0, 0, 0);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ choice ESP32_REV_MIN
|
||||
|
||||
config ESP32_REV_MIN_0
|
||||
bool "Rev 0"
|
||||
# Brownout on Rev 0 is bugged, must use interrupt
|
||||
select ESP_SYSTEM_BROWNOUT_INTR
|
||||
config ESP32_REV_MIN_1
|
||||
bool "Rev 1"
|
||||
config ESP32_REV_MIN_2
|
||||
|
@ -531,6 +531,18 @@ menu "ESP System Settings"
|
||||
# Insert chip-specific system config
|
||||
rsource "./port/soc/$IDF_TARGET/Kconfig.system"
|
||||
|
||||
config ESP_SYSTEM_BROWNOUT_INTR
|
||||
bool
|
||||
default n
|
||||
help
|
||||
This config allows to trigger an interrupt when brownout detected. Software restart will be done
|
||||
at the end of the default callback.
|
||||
Two occasions need to restart the chip with interrupt so far.
|
||||
(1). For ESP32 version 1, brown-out reset function doesn't work (see ESP32 errata 3.4).
|
||||
So that we must restart from interrupt.
|
||||
(2). For special workflow, the chip needs do more things instead of restarting directly. This part
|
||||
needs to be done in callback function of interrupt.
|
||||
|
||||
endmenu # ESP System Settings
|
||||
|
||||
menu "IPC (Inter-Processor Call)"
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "esp_private/system_internal.h"
|
||||
#include "esp_private/rtc_ctrl.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
@ -18,6 +19,9 @@
|
||||
#include "esp_cpu.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "hal/cpu_hal.h"
|
||||
#include "esp_attr.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#include "hal/brownout_hal.h"
|
||||
|
||||
@ -29,48 +33,58 @@
|
||||
#define BROWNOUT_DET_LVL 0
|
||||
#endif
|
||||
|
||||
#if SOC_BROWNOUT_RESET_SUPPORTED
|
||||
#define BROWNOUT_RESET_EN true
|
||||
#else
|
||||
#define BROWNOUT_RESET_EN false
|
||||
#endif // SOC_BROWNOUT_RESET_SUPPORTED
|
||||
|
||||
#ifndef SOC_BROWNOUT_RESET_SUPPORTED
|
||||
static void rtc_brownout_isr_handler(void *arg)
|
||||
#if CONFIG_ESP_SYSTEM_BROWNOUT_INTR
|
||||
IRAM_ATTR static void rtc_brownout_isr_handler(void *arg)
|
||||
{
|
||||
/* Normally RTC ISR clears the interrupt flag after the application-supplied
|
||||
* handler returns. Since restart is called here, the flag needs to be
|
||||
* cleared manually.
|
||||
*/
|
||||
brownout_hal_intr_clear();
|
||||
/* Stall the other CPU to make sure the code running there doesn't use UART
|
||||
* at the same time as the following esp_rom_printf.
|
||||
*/
|
||||
// Stop the other core.
|
||||
esp_cpu_stall(!cpu_hal_get_core_id());
|
||||
esp_reset_reason_set_hint(ESP_RST_BROWNOUT);
|
||||
#if CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
if (spi_flash_brownout_need_reset()) {
|
||||
bootloader_flash_reset_chip();
|
||||
} else
|
||||
#endif // CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
{
|
||||
esp_rom_printf("\r\nBrownout detector was triggered\r\n\r\n");
|
||||
}
|
||||
|
||||
esp_restart_noos();
|
||||
}
|
||||
#endif // not SOC_BROWNOUT_RESET_SUPPORTED
|
||||
#endif // CONFIG_ESP_SYSTEM_BROWNOUT_INTR
|
||||
|
||||
void esp_brownout_init(void)
|
||||
{
|
||||
#if CONFIG_ESP_SYSTEM_BROWNOUT_INTR
|
||||
brownout_hal_config_t cfg = {
|
||||
.threshold = BROWNOUT_DET_LVL,
|
||||
.enabled = true,
|
||||
.reset_enabled = BROWNOUT_RESET_EN,
|
||||
.reset_enabled = false,
|
||||
.flash_power_down = true,
|
||||
.rf_power_down = true,
|
||||
};
|
||||
|
||||
brownout_hal_config(&cfg);
|
||||
|
||||
|
||||
#ifndef SOC_BROWNOUT_RESET_SUPPORTED
|
||||
rtc_isr_register(rtc_brownout_isr_handler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M);
|
||||
|
||||
brownout_hal_intr_clear();
|
||||
rtc_isr_register(rtc_brownout_isr_handler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M, RTC_INTR_FLAG_IRAM);
|
||||
brownout_hal_intr_enable(true);
|
||||
#endif // not SOC_BROWNOUT_RESET_SUPPORTED
|
||||
|
||||
#else // brownout without interrupt
|
||||
|
||||
brownout_hal_config_t cfg = {
|
||||
.threshold = BROWNOUT_DET_LVL,
|
||||
.enabled = true,
|
||||
.reset_enabled = true,
|
||||
.flash_power_down = true,
|
||||
.rf_power_down = true,
|
||||
};
|
||||
|
||||
brownout_hal_config(&cfg);
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_brownout_disable(void)
|
||||
@ -80,10 +94,8 @@ void esp_brownout_disable(void)
|
||||
};
|
||||
|
||||
brownout_hal_config(&cfg);
|
||||
|
||||
#ifndef SOC_BROWNOUT_RESET_SUPPORTED
|
||||
#if CONFIG_ESP_SYSTEM_BROWNOUT_INTR
|
||||
brownout_hal_intr_enable(false);
|
||||
|
||||
rtc_isr_deregister(rtc_brownout_isr_handler, NULL);
|
||||
#endif // not SOC_BROWNOUT_RESET_SUPPORTED
|
||||
#endif // CONFIG_ESP_SYSTEM_BROWNOUT_INTR
|
||||
}
|
||||
|
@ -66,7 +66,7 @@
|
||||
|
||||
#include "esp_pthread.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
#include "esp_private/brownout.h"
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
@ -301,6 +301,9 @@ static void do_core_init(void)
|
||||
esp_err_t flash_ret = esp_flash_init_default_chip();
|
||||
assert(flash_ret == ESP_OK);
|
||||
(void)flash_ret;
|
||||
#if CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
spi_flash_needs_reset_check();
|
||||
#endif // CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
|
||||
|
@ -1,20 +1,13 @@
|
||||
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hal/brownout_hal.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
void brownout_hal_config(const brownout_hal_config_t *cfg)
|
||||
{
|
||||
@ -35,7 +28,7 @@ void brownout_hal_intr_enable(bool enable)
|
||||
RTCCNTL.int_ena.rtc_brown_out = enable;
|
||||
}
|
||||
|
||||
void brownout_hal_intr_clear(void)
|
||||
IRAM_ATTR void brownout_hal_intr_clear(void)
|
||||
{
|
||||
RTCCNTL.int_clr.rtc_brown_out = 1;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
#include "regi2c_brownout.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
|
||||
void brownout_hal_config(const brownout_hal_config_t *cfg)
|
||||
@ -31,7 +32,7 @@ void brownout_hal_intr_enable(bool enable)
|
||||
RTCCNTL.int_ena.rtc_brown_out = enable;
|
||||
}
|
||||
|
||||
void brownout_hal_intr_clear(void)
|
||||
IRAM_ATTR void brownout_hal_intr_clear(void)
|
||||
{
|
||||
RTCCNTL.int_clr.rtc_brown_out = 1;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
#include "regi2c_brownout.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
|
||||
void brownout_hal_config(const brownout_hal_config_t *cfg)
|
||||
@ -31,7 +32,7 @@ void brownout_hal_intr_enable(bool enable)
|
||||
RTCCNTL.int_ena.rtc_brown_out = enable;
|
||||
}
|
||||
|
||||
void brownout_hal_intr_clear(void)
|
||||
IRAM_ATTR void brownout_hal_intr_clear(void)
|
||||
{
|
||||
RTCCNTL.int_clr.rtc_brown_out = 1;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "i2c_pmu.h"
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
#include "regi2c_brownout.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
|
||||
void brownout_hal_config(const brownout_hal_config_t *cfg)
|
||||
@ -32,7 +33,7 @@ void brownout_hal_intr_enable(bool enable)
|
||||
RTCCNTL.int_ena.rtc_brown_out = enable;
|
||||
}
|
||||
|
||||
void brownout_hal_intr_clear(void)
|
||||
IRAM_ATTR void brownout_hal_intr_clear(void)
|
||||
{
|
||||
RTCCNTL.int_clr.rtc_brown_out = 1;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
#include "regi2c_brownout.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
|
||||
void brownout_hal_config(const brownout_hal_config_t *cfg)
|
||||
{
|
||||
@ -33,7 +33,7 @@ void brownout_hal_intr_enable(bool enable)
|
||||
RTCCNTL.int_ena.rtc_brown_out = enable;
|
||||
}
|
||||
|
||||
void brownout_hal_intr_clear(void)
|
||||
IRAM_ATTR void brownout_hal_intr_clear(void)
|
||||
{
|
||||
RTCCNTL.int_clr.rtc_brown_out = 1;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
#include "regi2c_brownout.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
|
||||
void brownout_hal_config(const brownout_hal_config_t *cfg)
|
||||
@ -32,7 +33,7 @@ void brownout_hal_intr_enable(bool enable)
|
||||
RTCCNTL.int_ena.rtc_brown_out = enable;
|
||||
}
|
||||
|
||||
void brownout_hal_intr_clear(void)
|
||||
IRAM_ATTR void brownout_hal_intr_clear(void)
|
||||
{
|
||||
RTCCNTL.int_clr.rtc_brown_out = 1;
|
||||
}
|
||||
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
|
@ -127,7 +127,6 @@
|
||||
#define SOC_ADC_RTC_MAX_BITWIDTH (12)
|
||||
#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1)
|
||||
|
||||
|
||||
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
|
||||
#if SOC_CAPS_ECO_VER >= 1
|
||||
#define SOC_BROWNOUT_RESET_SUPPORTED 1
|
||||
|
@ -3,10 +3,6 @@
|
||||
# using gen_soc_caps_kconfig.py, do not edit manually
|
||||
#####################################################
|
||||
|
||||
config SOC_BROWNOUT_RESET_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CPU_BREAKPOINTS_NUM
|
||||
int
|
||||
default 2
|
||||
@ -287,6 +283,10 @@ config SOC_APB_BACKUP_DMA
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BROWNOUT_RESET_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_DS_SIGNATURE_MAX_BIT_LEN
|
||||
int
|
||||
default 4096
|
||||
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SOC_BROWNOUT_RESET_SUPPORTED 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -100,7 +100,7 @@
|
||||
#define SOC_APB_BACKUP_DMA (1)
|
||||
|
||||
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
|
||||
#include "brownout_caps.h"
|
||||
#define SOC_BROWNOUT_RESET_SUPPORTED 1
|
||||
|
||||
/*-------------------------- CPU CAPS ----------------------------------------*/
|
||||
#include "cpu_caps.h"
|
||||
|
@ -25,6 +25,7 @@ else()
|
||||
set(srcs
|
||||
"partition.c"
|
||||
"partition_target.c"
|
||||
"flash_brownout_hook.c"
|
||||
)
|
||||
|
||||
if(CONFIG_ESPTOOLPY_OCT_FLASH)
|
||||
|
@ -209,6 +209,28 @@ menu "SPI Flash driver"
|
||||
|
||||
See example: custom_chip_driver under examples/storage for more details.
|
||||
|
||||
menu "SPI Flash behavior when brownout"
|
||||
|
||||
config SPI_FLASH_BROWNOUT_RESET_XMC
|
||||
bool "Enable sending reset when brownout for XMC flash chips"
|
||||
default y
|
||||
select SPI_FLASH_BROWNOUT_RESET
|
||||
help
|
||||
When this option is selected, the patch will be enabled for XMC.
|
||||
Follow the recommended flow by XMC for better stability.
|
||||
|
||||
DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||
|
||||
config SPI_FLASH_BROWNOUT_RESET
|
||||
bool
|
||||
default y
|
||||
select ESP_SYSTEM_BROWNOUT_INTR
|
||||
help
|
||||
When brownout happens during flash erase/write operations,
|
||||
send reset command to stop the flash operations to improve stability.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Auto-detect flash chips"
|
||||
visible if !SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST
|
||||
|
||||
|
39
components/spi_flash/flash_brownout_hook.c
Normal file
39
components/spi_flash/flash_brownout_hook.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_attr.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_spiflash.h"
|
||||
|
||||
#if CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
|
||||
static bool flash_brownout_needs_reset = false;
|
||||
static bool flash_erasing = false;
|
||||
|
||||
// This function could be called in startup
|
||||
void spi_flash_needs_reset_check(void)
|
||||
{
|
||||
// Currently only XMC is suggested to reset when brownout
|
||||
#if CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC
|
||||
if ((g_rom_flashchip.device_id >> 16) == 0x20) {
|
||||
flash_brownout_needs_reset = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void spi_flash_set_erasing_flag(bool status)
|
||||
{
|
||||
flash_erasing = status;
|
||||
}
|
||||
|
||||
bool spi_flash_brownout_need_reset(void)
|
||||
{
|
||||
return (flash_brownout_needs_reset && flash_erasing);
|
||||
}
|
||||
|
||||
#endif //CONFIG_SPI_FLASH_BROWNOUT_RESET
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "esp_err.h"
|
||||
@ -80,6 +72,11 @@ typedef struct {
|
||||
/** Called for get system time. */
|
||||
int64_t (*get_system_time)(void *arg);
|
||||
|
||||
#define SPI_FLASH_OS_IS_ERASING_STATUS_FLAG BIT(0)
|
||||
|
||||
/** Call to set flash operation status */
|
||||
void (*set_flash_op_status)(uint32_t op_status);
|
||||
|
||||
} esp_flash_os_functions_t;
|
||||
|
||||
/** @brief Structure to describe a SPI flash chip connected to the system.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -101,6 +101,28 @@ bool spi_timing_is_tuned(void);
|
||||
*/
|
||||
void spi_flash_set_vendor_required_regs(void);
|
||||
|
||||
/**
|
||||
* @brief Judge whether need to reset flash when brownout.
|
||||
* Set` flash_brownout_needs_reset` inside the function if really need reset.
|
||||
*/
|
||||
void spi_flash_needs_reset_check(void);
|
||||
|
||||
/**
|
||||
* @brief Set flag to reset flash. set when erase chip or program chip
|
||||
*
|
||||
* @param bool status. True if flash is eraing. False if flash is not erasing.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void spi_flash_set_erasing_flag(bool status);
|
||||
|
||||
/**
|
||||
* @brief Judge whether need to reset flash when brownout.
|
||||
*
|
||||
* @return true if need reset, otherwise false.
|
||||
*/
|
||||
bool spi_flash_brownout_need_reset(void);
|
||||
|
||||
/**
|
||||
* @brief Enable SPI flash high performance mode.
|
||||
*
|
||||
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "hal/spi_flash_hal.h"
|
||||
|
@ -9,6 +9,7 @@ entries:
|
||||
spi_flash_chip_boya (noflash)
|
||||
spi_flash_chip_th (noflash)
|
||||
memspi_host_driver (noflash)
|
||||
flash_brownout_hook (noflash)
|
||||
|
||||
if IDF_TARGET_ESP32S3 = y:
|
||||
spi_flash_timing_tuning (noflash)
|
||||
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -20,6 +12,7 @@
|
||||
#include "hal/spi_flash_encrypt_hal.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
|
||||
typedef struct flash_chip_dummy {
|
||||
uint8_t dio_dummy_bitlen;
|
||||
@ -69,6 +62,12 @@ const DRAM_ATTR flash_chip_op_timeout_t spi_flash_chip_generic_timeout = {
|
||||
.page_program_timeout = SPI_FLASH_GENERIC_PAGE_PROGRAM_TIMEOUT_MS * 1000,
|
||||
};
|
||||
|
||||
#define SET_FLASH_ERASE_STATUS(CHIP, status) do { \
|
||||
if (CHIP->os_func->set_flash_op_status) { \
|
||||
CHIP->os_func->set_flash_op_status(status); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static const char TAG[] = "chip_generic";
|
||||
|
||||
#ifndef CONFIG_SPI_FLASH_ROM_IMPL
|
||||
@ -130,6 +129,7 @@ esp_err_t spi_flash_chip_generic_erase_chip(esp_flash_t *chip)
|
||||
}
|
||||
//The chip didn't accept the previous write command. Ignore this in preparation stage.
|
||||
if (err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED) {
|
||||
SET_FLASH_ERASE_STATUS(chip, SPI_FLASH_OS_IS_ERASING_STATUS_FLAG);
|
||||
chip->host->driver->erase_chip(chip->host);
|
||||
chip->busy = 1;
|
||||
#ifdef CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED
|
||||
@ -137,6 +137,7 @@ esp_err_t spi_flash_chip_generic_erase_chip(esp_flash_t *chip)
|
||||
#else
|
||||
err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->chip_erase_timeout);
|
||||
#endif
|
||||
SET_FLASH_ERASE_STATUS(chip, 0);
|
||||
}
|
||||
// Ensure WEL is 0, even if the erase failed.
|
||||
if (err == ESP_ERR_NOT_SUPPORTED) {
|
||||
@ -154,6 +155,7 @@ esp_err_t spi_flash_chip_generic_erase_sector(esp_flash_t *chip, uint32_t start_
|
||||
}
|
||||
//The chip didn't accept the previous write command. Ignore this in preparationstage.
|
||||
if (err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED) {
|
||||
SET_FLASH_ERASE_STATUS(chip, SPI_FLASH_OS_IS_ERASING_STATUS_FLAG);
|
||||
chip->host->driver->erase_sector(chip->host, start_address);
|
||||
chip->busy = 1;
|
||||
#ifdef CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED
|
||||
@ -161,6 +163,7 @@ esp_err_t spi_flash_chip_generic_erase_sector(esp_flash_t *chip, uint32_t start_
|
||||
#else
|
||||
err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->sector_erase_timeout);
|
||||
#endif
|
||||
SET_FLASH_ERASE_STATUS(chip, 0);
|
||||
}
|
||||
// Ensure WEL is 0, even if the erase failed.
|
||||
if (err == ESP_ERR_NOT_SUPPORTED) {
|
||||
@ -178,6 +181,7 @@ esp_err_t spi_flash_chip_generic_erase_block(esp_flash_t *chip, uint32_t start_a
|
||||
}
|
||||
//The chip didn't accept the previous write command. Ignore this in preparationstage.
|
||||
if (err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED) {
|
||||
SET_FLASH_ERASE_STATUS(chip, SPI_FLASH_OS_IS_ERASING_STATUS_FLAG);
|
||||
chip->host->driver->erase_block(chip->host, start_address);
|
||||
chip->busy = 1;
|
||||
#ifdef CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED
|
||||
@ -185,6 +189,7 @@ esp_err_t spi_flash_chip_generic_erase_block(esp_flash_t *chip, uint32_t start_a
|
||||
#else
|
||||
err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->block_erase_timeout);
|
||||
#endif
|
||||
SET_FLASH_ERASE_STATUS(chip, 0);
|
||||
}
|
||||
// Ensure WEL is 0, even if the erase failed.
|
||||
if (err == ESP_ERR_NOT_SUPPORTED) {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_compiler.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
|
||||
#include "driver/spi_common_internal.h"
|
||||
|
||||
@ -185,6 +186,13 @@ static IRAM_ATTR esp_err_t main_flash_region_protected(void* arg, size_t start_a
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static IRAM_ATTR void main_flash_op_status(uint32_t op_status)
|
||||
{
|
||||
bool is_erasing = op_status & SPI_FLASH_OS_IS_ERASING_STATUS_FLAG;
|
||||
spi_flash_set_erasing_flag(is_erasing);
|
||||
}
|
||||
|
||||
static DRAM_ATTR spi1_app_func_arg_t main_flash_arg = {};
|
||||
|
||||
//for SPI1, we have to disable the cache and interrupts before using the SPI bus
|
||||
@ -197,6 +205,11 @@ static const DRAM_ATTR esp_flash_os_functions_t esp_flash_spi1_default_os_functi
|
||||
.release_temp_buffer = release_buffer_malloc,
|
||||
.check_yield = spi1_flash_os_check_yield,
|
||||
.yield = spi1_flash_os_yield,
|
||||
#if CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
.set_flash_op_status = main_flash_op_status,
|
||||
#else
|
||||
.set_flash_op_status = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const esp_flash_os_functions_t esp_flash_spi23_default_os_functions = {
|
||||
@ -208,6 +221,7 @@ static const esp_flash_os_functions_t esp_flash_spi23_default_os_functions = {
|
||||
.region_protected = NULL,
|
||||
.check_yield = NULL,
|
||||
.yield = NULL,
|
||||
.set_flash_op_status = NULL,
|
||||
};
|
||||
|
||||
static bool use_bus_lock(int host_id)
|
||||
|
@ -775,7 +775,6 @@ components/hal/aes_hal.c
|
||||
components/hal/cpu_hal.c
|
||||
components/hal/dac_hal.c
|
||||
components/hal/ds_hal.c
|
||||
components/hal/esp32/brownout_hal.c
|
||||
components/hal/esp32/gpio_hal_workaround.c
|
||||
components/hal/esp32/include/hal/aes_ll.h
|
||||
components/hal/esp32/include/hal/can_hal.h
|
||||
@ -859,7 +858,6 @@ components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h
|
||||
components/hal/esp32s3/interrupt_descriptor_table.c
|
||||
components/hal/include/hal/aes_hal.h
|
||||
components/hal/include/hal/aes_types.h
|
||||
components/hal/include/hal/brownout_hal.h
|
||||
components/hal/include/hal/cpu_types.h
|
||||
components/hal/include/hal/dac_hal.h
|
||||
components/hal/include/hal/dac_types.h
|
||||
@ -1536,10 +1534,8 @@ components/soc/include/soc/usb_periph.h
|
||||
components/soc/lldesc.c
|
||||
components/soc/soc_include_legacy_warn.c
|
||||
components/spi_flash/cache_utils.h
|
||||
components/spi_flash/include/esp_flash.h
|
||||
components/spi_flash/include/esp_spi_flash.h
|
||||
components/spi_flash/include/esp_spi_flash_counters.h
|
||||
components/spi_flash/include/memspi_host_driver.h
|
||||
components/spi_flash/include/spi_flash_chip_boya.h
|
||||
components/spi_flash/include/spi_flash_chip_driver.h
|
||||
components/spi_flash/include/spi_flash_chip_gd.h
|
||||
@ -1553,7 +1549,6 @@ components/spi_flash/sim/flash_mock_util.c
|
||||
components/spi_flash/sim/sdkconfig/sdkconfig.h
|
||||
components/spi_flash/spi_flash_chip_boya.c
|
||||
components/spi_flash/spi_flash_chip_gd.c
|
||||
components/spi_flash/spi_flash_chip_generic.c
|
||||
components/spi_flash/spi_flash_chip_issi.c
|
||||
components/spi_flash/spi_flash_chip_mxic.c
|
||||
components/spi_flash/spi_flash_chip_mxic_opi.c
|
||||
|
Loading…
Reference in New Issue
Block a user