diff --git a/components/hal/esp32c2/include/hal/spimem_flash_ll.h b/components/hal/esp32c2/include/hal/spimem_flash_ll.h index de92fc45cc..14a6ad0899 100644 --- a/components/hal/esp32c2/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32c2/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ #include // For MIN/MAX #include #include - +#include "hal/misc.h" #include "soc/spi_periph.h" #include "hal/spi_types.h" #include "hal/spi_flash_types.h" @@ -144,7 +144,7 @@ static inline void spimem_flash_ll_auto_resume_init(spi_mem_dev_t *dev, bool aut */ static inline void spimem_flash_ll_suspend_cmd_setup(spi_mem_dev_t *dev, uint32_t sus_cmd) { - dev->flash_sus_cmd.flash_pes_command = sus_cmd; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_cmd, flash_pes_command, sus_cmd); } /** @@ -156,7 +156,7 @@ static inline void spimem_flash_ll_suspend_cmd_setup(spi_mem_dev_t *dev, uint32_ */ static inline void spimem_flash_ll_resume_cmd_setup(spi_mem_dev_t *dev, uint32_t res_cmd) { - dev->flash_sus_cmd.flash_per_command = res_cmd; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_cmd, flash_per_command, res_cmd); } /** @@ -168,7 +168,7 @@ static inline void spimem_flash_ll_resume_cmd_setup(spi_mem_dev_t *dev, uint32_t */ static inline void spimem_flash_ll_rd_sus_cmd_setup(spi_mem_dev_t *dev, uint32_t pesr_cmd) { - dev->flash_sus_cmd.wait_pesr_command = pesr_cmd; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_cmd, wait_pesr_command, pesr_cmd); } /** @@ -205,7 +205,7 @@ static inline void spimem_flash_ll_res_check_sus_setup(spi_mem_dev_t *dev, bool static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint32_t sus_conf) { dev->flash_sus_ctrl.frd_sus_2b = 0; - dev->flash_sus_ctrl.pesr_end_msk = sus_conf; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf); } /** @@ -236,13 +236,14 @@ static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t c * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { - dev->flash_waiti_ctrl.waiti_cmd = 0x05; - dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti; - dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); + dev->flash_sus_ctrl.flash_per_wait_en = per_waiti; + dev->flash_sus_ctrl.flash_pes_wait_en = pes_waiti; } /** @@ -515,11 +516,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** diff --git a/components/hal/esp32c3/include/hal/spimem_flash_ll.h b/components/hal/esp32c3/include/hal/spimem_flash_ll.h index 873142de39..bed40c5af8 100644 --- a/components/hal/esp32c3/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32c3/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -238,13 +238,14 @@ static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t c * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); - dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti; - dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti; + dev->flash_sus_ctrl.flash_per_wait_en = per_waiti; + dev->flash_sus_ctrl.flash_pes_wait_en = pes_waiti; } /** @@ -517,11 +518,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** diff --git a/components/hal/esp32c5/include/hal/spimem_flash_ll.h b/components/hal/esp32c5/include/hal/spimem_flash_ll.h index 531d559265..2efea74ba4 100644 --- a/components/hal/esp32c5/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32c5/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -242,13 +242,14 @@ static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t c * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); - dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti; - dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti; + dev->flash_sus_ctrl.flash_per_wait_en = per_waiti; + dev->flash_sus_ctrl.flash_pes_wait_en = pes_waiti; } /** @@ -521,11 +522,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** diff --git a/components/hal/esp32c6/include/hal/spimem_flash_ll.h b/components/hal/esp32c6/include/hal/spimem_flash_ll.h index dae851b685..20b54c18f6 100644 --- a/components/hal/esp32c6/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32c6/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -239,13 +239,14 @@ static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t c * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); - dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti; - dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti; + dev->flash_sus_ctrl.flash_per_wait_en = per_waiti; + dev->flash_sus_ctrl.flash_pes_wait_en = pes_waiti; } /** @@ -518,11 +519,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** @@ -557,7 +555,7 @@ static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr) { dev->cache_fctrl.usr_addr_4byte = 0; - dev->rd_status.wb_mode = extra_addr; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rd_status, wb_mode, extra_addr); } /** diff --git a/components/hal/esp32c61/include/hal/spimem_flash_ll.h b/components/hal/esp32c61/include/hal/spimem_flash_ll.h index d60bc1d978..284ea2287d 100644 --- a/components/hal/esp32c61/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32c61/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -242,13 +242,14 @@ static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t c * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); - dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti; - dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti; + dev->flash_sus_ctrl.flash_per_wait_en = per_waiti; + dev->flash_sus_ctrl.flash_pes_wait_en = pes_waiti; } /** @@ -521,11 +522,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** @@ -559,8 +557,8 @@ static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t */ static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr) { - dev->cache_fctrl.usr_addr_4byte = 0; - dev->rd_status.wb_mode = extra_addr; + dev->cache_fctrl.cache_usr_addr_4byte = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rd_status, wb_mode, extra_addr); } /** diff --git a/components/hal/esp32h2/include/hal/spimem_flash_ll.h b/components/hal/esp32h2/include/hal/spimem_flash_ll.h index 95cee518a8..92749a2106 100644 --- a/components/hal/esp32h2/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32h2/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -240,13 +240,14 @@ static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t c * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); - dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti; - dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti; + dev->flash_sus_ctrl.flash_per_wait_en = per_waiti; + dev->flash_sus_ctrl.flash_pes_wait_en = pes_waiti; } /** @@ -539,11 +540,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** @@ -578,7 +576,7 @@ static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr) { dev->cache_fctrl.usr_addr_4byte = 0; - dev->rd_status.wb_mode = extra_addr; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rd_status, wb_mode, extra_addr); } /** diff --git a/components/hal/esp32p4/include/hal/spimem_flash_ll.h b/components/hal/esp32p4/include/hal/spimem_flash_ll.h index 2fc156aaa2..d4b043ff40 100644 --- a/components/hal/esp32p4/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32p4/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -244,13 +244,14 @@ static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t c * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); - dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti; - dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti; + dev->flash_sus_ctrl.flash_per_wait_en = per_waiti; + dev->flash_sus_ctrl.flash_pes_wait_en = pes_waiti; } /** @@ -527,11 +528,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** diff --git a/components/hal/esp32s2/include/hal/spimem_flash_ll.h b/components/hal/esp32s2/include/hal/spimem_flash_ll.h index 3b5611146a..35411eb591 100644 --- a/components/hal/esp32s2/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32s2/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -209,12 +209,13 @@ static inline void spimem_flash_ll_res_check_sus_setup(spi_mem_dev_t *dev, bool * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { - HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); // Set the command to send, to fetch flash status reg value. - dev->flash_waiti_ctrl.waiti_en = auto_waiti; // enable auto wait-idle function. + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); + dev->flash_waiti_ctrl.waiti_en = (per_waiti | pes_waiti); // enable auto wait-idle function. } /** @@ -457,11 +458,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** diff --git a/components/hal/esp32s3/include/hal/spimem_flash_ll.h b/components/hal/esp32s3/include/hal/spimem_flash_ll.h index 9b07256b4d..07c9165c1d 100644 --- a/components/hal/esp32s3/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32s3/include/hal/spimem_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -264,14 +264,15 @@ static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *de * Initialize auto wait idle mode * * @param dev Beginning address of the peripheral registers. - * @param auto_waiti Enable/disable auto wait-idle function + * @param per_waiti Enable wait-idle with time delay function after resume. + * @param pes_waiti Enable wait-idle with time delay function after suspend. */ -static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti) +static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool per_waiti, bool pes_waiti) { - HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); // Set the command to send, to fetch flash status reg value. - dev->flash_waiti_ctrl.waiti_en = auto_waiti; // enable auto wait-idle function. - dev->flash_sus_cmd.flash_per_wait_en = 1; - dev->flash_sus_cmd.flash_pes_wait_en = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); + dev->flash_waiti_ctrl.waiti_en = (per_waiti | pes_waiti); // enable auto wait-idle function. + dev->flash_sus_cmd.flash_per_wait_en = per_waiti; + dev->flash_sus_cmd.flash_pes_wait_en = pes_waiti; } /** @@ -534,11 +535,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen) { dev->user.usr_command = 1; - typeof(dev->user2) user2 = { - .usr_command_value = command, - .usr_command_bitlen = (bitlen - 1), - }; - dev->user2.val = user2.val; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1)); } /** diff --git a/components/hal/include/hal/spi_flash_hal.h b/components/hal/include/hal/spi_flash_hal.h index e4e2cd7e2e..b50ac7726b 100644 --- a/components/hal/include/hal/spi_flash_hal.h +++ b/components/hal/include/hal/spi_flash_hal.h @@ -57,6 +57,7 @@ typedef struct { #define SPI_FLASH_HOST_CONTEXT_SLICER_FLAG_DTR BIT(0) ///< Slice data according to DTR mode, the address and length must be even (A0=0). int freq_mhz; /// Flash clock frequency. uint8_t tsus_val; ///< Tsus value of suspend (us) + bool auto_waiti_pes; ///< True for auto-wait idle after suspend command. False for using time delay. } spi_flash_hal_context_t; ESP_STATIC_ASSERT(sizeof(spi_flash_hal_context_t) == 48, "size of spi_flash_hal_context_t incorrect. Please check data compatibility with the ROM"); @@ -90,7 +91,8 @@ typedef struct { esp_flash_io_mode_t default_io_mode; ///< Default flash io mode. int freq_mhz; ///< SPI flash clock speed (MHZ). int clock_src_freq; ///< SPI flash clock source (MHZ). - uint8_t tsus_val; ///< Tsus value of suspend (us) + uint8_t tsus_val; ///< Tsus value of suspend (us). + bool auto_waiti_pes; ///< True for auto-wait idle after suspend command. False for using time delay. } spi_flash_hal_config_t; /** diff --git a/components/hal/spi_flash_hal.c b/components/hal/spi_flash_hal.c index 295b214f7b..b57c43c836 100644 --- a/components/hal/spi_flash_hal.c +++ b/components/hal/spi_flash_hal.c @@ -126,6 +126,7 @@ esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_ data_out->flags |= SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_SUSPEND; data_out->flags |= SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_RESUME; data_out->tsus_val = cfg->tsus_val; + data_out->auto_waiti_pes = cfg->auto_waiti_pes; } #if CONFIG_SPI_FLASH_SOFTWARE_RESUME diff --git a/components/hal/spi_flash_hal_iram.c b/components/hal/spi_flash_hal_iram.c index eae0f54031..faf55a6adb 100644 --- a/components/hal/spi_flash_hal_iram.c +++ b/components/hal/spi_flash_hal_iram.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -145,7 +145,8 @@ void spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t *host) { spi_mem_dev_t *dev = (spi_mem_dev_t*)spi_flash_ll_get_hw(SPI1_HOST); spi_flash_hal_context_t* ctx = (spi_flash_hal_context_t*)host; - spimem_flash_ll_auto_wait_idle_init(dev, true); + bool pes_waiti_delay = ctx->auto_waiti_pes ? false : true; + spimem_flash_ll_auto_wait_idle_init(dev, true, pes_waiti_delay); if (ctx->freq_mhz == 120) { spimem_flash_ll_set_wait_idle_dummy_phase(dev, ctx->extra_dummy); } @@ -172,7 +173,7 @@ void spi_flash_hal_setup_auto_resume_mode(spi_flash_host_inst_t *host) void spi_flash_hal_disable_auto_suspend_mode(spi_flash_host_inst_t *host) { spi_mem_dev_t *dev = (spi_mem_dev_t *)spi_flash_ll_get_hw(SPI1_HOST); - spimem_flash_ll_auto_wait_idle_init(dev, false); + spimem_flash_ll_auto_wait_idle_init(dev, false, false); spimem_flash_ll_auto_suspend_init(dev, false); #if SOC_SPI_MEM_SUPPORT_CHECK_SUS spimem_flash_ll_sus_check_sus_setup(dev, false); diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 7875add83a..5a9a4e8d84 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -150,6 +150,17 @@ menu "Main Flash configuration" task can suspend the erase/program operation. When this option is enabled, task scheduler is disabled, only interrupt can suspend erase/program operation. + config SPI_FLASH_AUTO_CHECK_SUSPEND_STATUS + bool "Check flash status automatically after flash suspend" + default n + depends on SPI_FLASH_AUTO_SUSPEND + help + Majority flash supports to use flash register to judge if flash suspend status is + done or not. So enable this config, the behavior would use flash register WIP bit to judge + whether suspend is valid instead of waiting for a specific long time, which can save a + lot of time and benefit for performance improvement. + + endmenu endmenu diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 389565166e..e66980279f 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -387,6 +387,10 @@ esp_err_t esp_flash_init_default_chip(void) cfg.tsus_val = TSUS_VAL_SUSPEND; #endif // CONFIG_SPI_FLASH_AUTO_SUSPEND + #if CONFIG_SPI_FLASH_AUTO_CHECK_SUSPEND_STATUS + cfg.auto_waiti_pes = true; + #endif + //the host is already initialized, only do init for the data and load it to the host esp_err_t err = memspi_host_init_pointers(&esp_flash_default_host, &cfg); if (err != ESP_OK) { diff --git a/components/spi_flash/test_apps/esp_flash/CMakeLists.txt b/components/spi_flash/test_apps/esp_flash/CMakeLists.txt index 91389d9e26..889416b847 100644 --- a/components/spi_flash/test_apps/esp_flash/CMakeLists.txt +++ b/components/spi_flash/test_apps/esp_flash/CMakeLists.txt @@ -10,3 +10,8 @@ set(COMPONENTS main esptool_py) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(test_esp_flash_drv) + +message(STATUS "Checking memspi registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "spi_mem*" "spi1_mem*" + HAL_MODULES "spimem_flash")