/** ****************************************************************************** * @file stm32u5xx_hal_dcache.c * @author MCD Application Team * @brief DCACHE HAL module driver. * This file provides firmware functions to manage the following * functionalities of the DCACHE. * + Initialization and Configuration * + Cache coherency command * + Monitoring management ****************************************************************************** * @attention * * Copyright (c) 2021 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** @verbatim =============================================================================== ##### How to use this driver ##### =============================================================================== [..] (#) Configure and enable the MPU to override default config if needed, please refers to ARM manual for default memory attribute. Then enable DCache. [..] (+) Use HAL_DCACHE_Invalidate() to invalidate the full cache content: (++) Cache content is lost, and reloaded when needed. (++) Used for complete invalidate of the dcache in case. (++) Blocking call until operation is done. (+) Use HAL_DCACHE_InvalidateByAddr() to invalidate cache content for specific range: (++) Cache content for specific range is lost, and reloaded when needed. (++) Used when excepting a buffer to be updated by a peripheral (typically DMA transfer) (++) Blocking call until operation is done. (+) Use HAL_DCACHE_CleanByAddr() to clean cache content for a specific range: (++) Cache content for specific range is written back to memory. (++) Used when buffer is updated by CPU before usage by a peripheral (typically DMA transfer) (++) Blocking call until operation is done. (+) Use HAL_DCACHE_CleanInvalidateByAddr() to clean and invalidate cache content for a specific range: (++) Cache content for specific range is written back to memory, and reloaded when needed. (++) Used when sharing buffer between CPU and other peripheral. (++) Recommended to use for MPU reprogramming. (++) Blocking call until operation is done. *** Interrupt mode IO operation *** =================================== [..] (+) Configure the DCACHE interrupt priority using HAL_NVIC_SetPriority() (+) Enable the DCACHE IRQ handler using HAL_NVIC_EnableIRQ() (+) Override weak definition for following callback (if needed): (++)HAL_DCACHE_CleanAndInvalidateByAddrCallback() (++)HAL_DCACHE_InvalidateCompleteCallback() (++)HAL_DCACHE_InvalidateByAddrCallback() (++)HAL_DCACHE_CleanByAddrCallback() (++)HAL_DCACHE_ErrorCallback() (+) Use HAL_DCACHE__IT() to start a DCache operation with IT enabled. (+) Use HAL_DCACHE_IRQHandler() called under DCACHE_IRQHandler() Interrupt subroutine [..] Use HAL_DCACHE_GetState() function to return the DCACHE state and HAL_DCACHE_GetError() in case of error detection. *** DCACHE HAL driver macros list *** ============================================= [..] Below the list of most used macros in DCACHE HAL driver. (+) __HAL_DCACHE_ENABLE_IT : Enable DCACHE interrupts. (+) __HAL_DCACHE_DISABLE_IT : Disable DCACHE interrupts. (+) __HAL_DCACHE_GET_IT_SOURCE: Check whether the specified DCACHE interrupt source is enabled or not. (+) __HAL_DCACHE_GET_FLAG : Check whether the selected DCACHE flag is set or not. (+) __HAL_DCACHE_CLEAR_FLAG : Clear the selected DCACHE flags. [..] (@) You can refer to the header file of the DCACHE HAL driver for more useful macros. [..] @endverbatim ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32u5xx_hal.h" /** @addtogroup STM32U5xx_HAL_Driver * @{ */ /** @defgroup DCACHE DCACHE * @brief HAL DCACHE module driver * @{ */ #ifdef HAL_DCACHE_MODULE_ENABLED /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /** @defgroup DCACHE_Private_Macros DCACHE Private Macros * @{ */ #define IS_DCACHE_REGION_SIZE(__SIZE__) ((__SIZE__) > 0U) #define IS_DCACHE_MONITOR_TYPE(__TYPE__) (((__TYPE__) & ~DCACHE_MONITOR_ALL) == 0U) #define IS_DCACHE_SINGLE_MONITOR_TYPE(__TYPE__) (((__TYPE__) == DCACHE_MONITOR_READ_HIT) || \ ((__TYPE__) == DCACHE_MONITOR_READ_MISS) || \ ((__TYPE__) == DCACHE_MONITOR_WRITE_HIT) || \ ((__TYPE__) == DCACHE_MONITOR_WRITE_MISS)) #define IS_DCACHE_READ_BURST_TYPE(__OUTPUTBURSTTYPE__) (((__OUTPUTBURSTTYPE__) == DCACHE_READ_BURST_WRAP) || \ ((__OUTPUTBURSTTYPE__) == DCACHE_READ_BURST_INCR)) /** * @} */ /* Private typedef -----------------------------------------------------------*/ /* Private constants ---------------------------------------------------------*/ /** @addtogroup DCACHE_Private_Constants DCACHE Private Constants * @{ */ #define DCACHE_COMMAND_TIMEOUT_VALUE 200U /* 200ms*/ #define DCACHE_DISABLE_TIMEOUT_VALUE 1U /* 1ms */ #define DCACHE_COMMAND_INVALIDATE DCACHE_CR_CACHECMD_1 #define DCACHE_COMMAND_CLEAN DCACHE_CR_CACHECMD_0 #define DCACHE_COMMAND_CLEAN_INVALIDATE (DCACHE_CR_CACHECMD_0|DCACHE_CR_CACHECMD_1) #define DCACHE_POLLING_MODE 0U #define DCACHE_IT_MODE 1U /** * @} */ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ static HAL_StatusTypeDef DCACHE_CommandByAddr(DCACHE_HandleTypeDef *hdcache, uint32_t Command, const uint32_t *const pAddr, uint32_t dSize, uint32_t mode); /* Exported functions --------------------------------------------------------*/ /** @defgroup DCACHE_Exported_Functions DCACHE Exported Functions * @{ */ /** @defgroup DCACHE_Exported_Functions_Group1 Initialization and de-initialization functions * @brief Initialization and Configuration functions * @verbatim =============================================================================== ##### Initialization and de-initialization functions ##### =============================================================================== [..] This subsection provides a set of functions allowing to initialize and deinitialize the DCACHEx peripheral: (+) User must implement HAL_DCACHE_MspInit() function in which he configures all related peripherals resources (CLOCK, MPU, IT and NVIC ). (+) Call the function HAL_DCACHE_Init() to configure the selected device with the selected configuration: (++) ReadBurstType (+) Call the function HAL_DCACHE_DeInit() to restore the reset configuration of the selected DCACHEx peripheral. @endverbatim * @{ */ /** * @brief Initializes the DCACHE according to the specified parameters * in the DCACHE_InitTypeDef and initialize the associated handle. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHE. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_Init(DCACHE_HandleTypeDef *hdcache) { HAL_StatusTypeDef status; /* Check the DCACHE handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_READ_BURST_TYPE(hdcache->Init.ReadBurstType)); if (hdcache->State == HAL_DCACHE_STATE_RESET) { /* Init the DCACHE Callback settings with legacy weak */ hdcache->ErrorCallback = HAL_DCACHE_ErrorCallback; hdcache->CleanByAddrCallback = HAL_DCACHE_CleanByAddrCallback; hdcache->InvalidateByAddrCallback = HAL_DCACHE_InvalidateByAddrCallback; hdcache->InvalidateCompleteCallback = HAL_DCACHE_InvalidateCompleteCallback; hdcache->CleanAndInvalidateByAddrCallback = HAL_DCACHE_CleanAndInvalidateByAddrCallback; if (hdcache->MspInitCallback == NULL) { hdcache->MspInitCallback = HAL_DCACHE_MspInit; } /* Init the low level hardware */ hdcache->MspInitCallback(hdcache); } /* Init the error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; /* Init the DCACHE handle state */ hdcache->State = HAL_DCACHE_STATE_READY; /* Set requested read burst type */ MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_HBURST, hdcache->Init.ReadBurstType); /* Enable the selected DCACHE peripheral */ status = HAL_DCACHE_Enable(hdcache); return status; } /** * @brief DeInitialize the Data cache. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_DeInit(DCACHE_HandleTypeDef *hdcache) { HAL_StatusTypeDef status; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /* Update the error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; /* Return to the reset state */ hdcache->State = HAL_DCACHE_STATE_RESET; /* Disable cache */ status = HAL_DCACHE_Disable(hdcache); /* reset monitor values */ (void)HAL_DCACHE_Monitor_Reset(hdcache, DCACHE_MONITOR_ALL); /* Reset all remaining bit */ WRITE_REG(hdcache->Instance->CR, 0U); WRITE_REG(hdcache->Instance->CMDRSADDRR, 0U); WRITE_REG(hdcache->Instance->CMDREADDRR, 0U); WRITE_REG(hdcache->Instance->FCR, DCACHE_FCR_CCMDENDF | DCACHE_FCR_CERRF | DCACHE_FCR_CBSYENDF); if (hdcache->MspDeInitCallback == NULL) { hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit; } /* DeInit the low level hardware */ hdcache->MspDeInitCallback(hdcache); return status; } /** * @brief Initialize the DCACHE MSP. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval None */ __weak void HAL_DCACHE_MspInit(DCACHE_HandleTypeDef *hdcache) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdcache); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DCACHE_MspInit can be implemented in the user file */ } /** * @brief DeInitialize the DCACHE MSP. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval None */ __weak void HAL_DCACHE_MspDeInit(DCACHE_HandleTypeDef *hdcache) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdcache); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DCACHE_MspDeInit can be implemented in the user file */ } /** @defgroup DCACHE_Exported_Functions_Group2 IO operation functions * @brief IO operation functions * @verbatim ============================================================================== ##### IO operation functions ##### ============================================================================== [..] This section provides functions allowing to: (+) Enable the Data cache. (+) Disable the Data cache. (+) Set Read Burst Type. (+) Invalidate the Data cache. (+) Invalidate the Data cache with interrupt. (+) Clean the Data cache by Addr. (+) Invalidate the Data cache by Addr. (+) Clean and Invalidate the Data cache by Addr. (+) Clean the Data cache by Addr with interrupt. (+) Invalidate the Data cache by Addr with interrupt. (+) Clean and Invalidate the Data cache by Addr with interrupt. @endverbatim * @{ */ /** * @brief Enable the Data cache. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_Enable(DCACHE_HandleTypeDef *hdcache) { HAL_StatusTypeDef status = HAL_OK; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /* Check no ongoing operation */ if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) { /* Return busy status */ status = HAL_BUSY; } else { /* Update the error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; /* Enable the selected DCACHE peripheral */ SET_BIT(hdcache->Instance->CR, DCACHE_CR_EN); } return status; } /** * @brief Disable the Data cache. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_Disable(DCACHE_HandleTypeDef *hdcache) { HAL_StatusTypeDef status = HAL_OK; uint32_t tickstart; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /* Check DCACHE handle status */ if (HAL_DCACHE_IsEnabled(hdcache) != 0U) { /* Update the error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; /* Change DCACHE handle state */ hdcache->State = HAL_DCACHE_STATE_READY; /* Disable the selected DCACHE peripheral */ CLEAR_BIT(hdcache->Instance->CR, DCACHE_CR_EN); /* Get timeout */ tickstart = HAL_GetTick(); /* Wait for end of data cache disabling */ while (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) { if ((HAL_GetTick() - tickstart) > DCACHE_DISABLE_TIMEOUT_VALUE) { if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) { /* Update error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT; /* Change the DCACHE handle state */ hdcache->State = HAL_DCACHE_STATE_ERROR; /* Return error status */ status = HAL_ERROR; break; } } } } return status; } /** * @brief Check whether the Data Cache is enabled or not. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval Status (0: disabled, 1: enabled) */ uint32_t HAL_DCACHE_IsEnabled(DCACHE_HandleTypeDef *hdcache) { return ((READ_BIT(hdcache->Instance->CR, DCACHE_CR_EN) != 0U) ? 1UL : 0UL); } /** * @brief Set Read Burst Type. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param ReadBurstType Burst type to be applied for Data Cache * DCACHE_READ_BURST_WRAP, DCACHE_READ_BURST_INC. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_SetReadBurstType(DCACHE_HandleTypeDef *hdcache, uint32_t ReadBurstType) { HAL_StatusTypeDef status = HAL_OK; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_READ_BURST_TYPE(ReadBurstType)); /* check DCACHE status */ if (HAL_DCACHE_IsEnabled(hdcache) == 0U) { /* Set requested read burst type */ MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_HBURST, ReadBurstType); } else { /* Update the error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_INVALID_OPERATION; /* Return error status */ status = HAL_ERROR; } return status; } /** * @brief Invalidate the Data cache. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @note This function waits for end of full cache invalidation * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_Invalidate(DCACHE_HandleTypeDef *hdcache) { HAL_StatusTypeDef status = HAL_OK; uint32_t tickstart; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /* Check no ongoing operation */ if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) { /* Return busy status */ status = HAL_BUSY; } else { /* Update the error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; /* Change DCACHE Handle state */ hdcache->State = HAL_DCACHE_STATE_READY; /* Make sure flags are reset */ WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF)); /* Set no operation on address range */ MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, 0U); /* Launch cache invalidation */ SET_BIT(hdcache->Instance->CR, DCACHE_CR_CACHEINV); /* Get timeout */ tickstart = HAL_GetTick(); /* Wait for end of cache invalidation */ while (READ_BIT(hdcache->Instance->SR, DCACHE_SR_BUSYF) != 0U) { if ((HAL_GetTick() - tickstart) > DCACHE_COMMAND_TIMEOUT_VALUE) { if (READ_BIT(hdcache->Instance->SR, DCACHE_SR_BUSYF) != 0U) { /* Update error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT; /* Change the DCACHE state */ hdcache->State = HAL_DCACHE_STATE_ERROR; /* Return error status */ status = HAL_ERROR; break; } } } } return status; } /** * @brief Invalidate the Data cache for a specific region. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param pAddr Start address of the region to be Invalidated * @param dSize Size of the region to be Invalidated(in bytes) * @note This function waits for end of cache Invalidation * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_InvalidateByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize) { HAL_StatusTypeDef status; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_REGION_SIZE(dSize)); status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_INVALIDATE, pAddr, dSize, DCACHE_POLLING_MODE); return status; } /** * @brief Clean the Data cache by Addr. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param pAddr Start address of the region to be Cleaned * @param dSize Size of the region to be Cleaned (in bytes) * @note This function waits for end of cache Clean * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_CleanByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize) { HAL_StatusTypeDef status; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_REGION_SIZE(dSize)); status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN, pAddr, dSize, DCACHE_POLLING_MODE); return status; } /** * @brief Clean and Invalidate the Data cache by Addr. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param pAddr Start address of the region to be Cleaned and Invalidated * @param dSize Size of the region to be Cleaned and Invalidated (in bytes) * @note This function waits for end of cache Clean and Invalidation * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_CleanInvalidByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize) { HAL_StatusTypeDef status; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_REGION_SIZE(dSize)); status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN_INVALIDATE, pAddr, dSize, DCACHE_POLLING_MODE); return status; } /** * @brief Invalidate the Data cache with interrupt. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @note This function launches maintenance operation and returns immediately. * User application shall resort to interrupt generation to check * the end of operation. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_Invalidate_IT(DCACHE_HandleTypeDef *hdcache) { HAL_StatusTypeDef status = HAL_OK; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /* Check no ongoing operation */ if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) { /* Return busy status */ status = HAL_BUSY; } else { /* Update the error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; /* Change DCACHE Handle state */ hdcache->State = HAL_DCACHE_STATE_READY; /* Make sure BSYENDF is reset */ WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF)); /* Set no operation on address range for callback under interrupt */ MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, 0U); /* Enable end of cache invalidation interrupt */ SET_BIT(hdcache->Instance->IER, DCACHE_IER_BSYENDIE); /* Launch cache invalidation */ SET_BIT(hdcache->Instance->CR, DCACHE_CR_CACHEINV); } return status; } /** * @brief Invalidate the Data cache by Addr with interrupt. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param pAddr Start address of the region to be Invalidated * @param dSize Size of the region to be Invalidated * @note This function launches maintenance operation and returns immediately. * User application shall resort to interrupt generation to check * the end of operation. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_InvalidateByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize) { HAL_StatusTypeDef status; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_REGION_SIZE(dSize)); status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_INVALIDATE, pAddr, dSize, DCACHE_IT_MODE); return status; } /** * @brief Clean the Data cache by Addr with interrupt. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param pAddr Start address of the region to be Cleaned * @param dSize Size of the region to be Cleaned * @note This function launches maintenance operation and returns immediately. * User application shall resort to interrupt generation to check * the end of operation. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_CleanByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize) { HAL_StatusTypeDef status; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_REGION_SIZE(dSize)); status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN, pAddr, dSize, DCACHE_IT_MODE); return status; } /** * @brief Clean and Invalidate the Data cache by Addr with interrupt. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param pAddr Start address of the region to be Cleaned and Invalidated * @param dSize Size of the region to be Cleaned and Invalidated * @note This function launches maintenance operation and returns immediately. * User application shall resort to interrupt generation to check * the end of operation. * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_CleanInvalidByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize) { HAL_StatusTypeDef status; /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_REGION_SIZE(dSize)); status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN_INVALIDATE, pAddr, dSize, DCACHE_IT_MODE); return status; } /** * @brief Handle the Data Cache interrupt request. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @note This API should be called under the DCACHE_IRQHandler(). * @retval None */ void HAL_DCACHE_IRQHandler(DCACHE_HandleTypeDef *hdcache) { /* Get current interrupt flags and interrupt sources value */ uint32_t itflags = READ_REG(hdcache->Instance->SR); uint32_t itsources = READ_REG(hdcache->Instance->IER); /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /* Check Data cache Error interrupt flag */ if (((itflags & itsources) & DCACHE_FLAG_ERROR) != 0U) { /* Clear DCACHE error pending flag */ __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_ERROR); /* Update data cache error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_EVICTION_CLEAN; /* Data cache error interrupt user callback */ hdcache->ErrorCallback(hdcache); } if (READ_BIT(hdcache->Instance->CR, DCACHE_CR_CACHECMD) == 0U) /* no operation by range */ { /* Clear DCACHE busyend pending flag */ __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_BUSYEND); /* Data cache invalidate complete interrupt user callback */ hdcache->InvalidateCompleteCallback(hdcache); } else if (READ_BIT(hdcache->Instance->CR, DCACHE_CR_CACHECMD_1 | DCACHE_CR_CACHECMD_0) == \ (DCACHE_CR_CACHECMD_1 | DCACHE_CR_CACHECMD_0)) { /* Clear DCACHE cmdend pending flag */ __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND); /* Data cache clean and invalidate range cmdend interrupt user callback */ hdcache->CleanAndInvalidateByAddrCallback(hdcache); } else if (READ_BIT(hdcache->Instance->CR, DCACHE_CR_CACHECMD_0) == DCACHE_CR_CACHECMD_0) { /* Clear DCACHE cmdend pending flag */ __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND); /* Data cache clean range cmdend interrupt user callback */ hdcache->CleanByAddrCallback(hdcache); } else { /* Clear DCACHE cmdend pending flag */ __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND); /* Data cache Invalidate range cmdend interrupt user callback */ hdcache->InvalidateByAddrCallback(hdcache); } } /** * @brief Cache clean command by address callback. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval None */ __weak void HAL_DCACHE_CleanByAddrCallback(DCACHE_HandleTypeDef *hdcache) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdcache); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DCACHE_CleanByAddrCallback() should be implemented in the user file */ } /** * @brief Cache Invalidate command by address callback. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval None */ __weak void HAL_DCACHE_InvalidateByAddrCallback(DCACHE_HandleTypeDef *hdcache) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdcache); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DCACHE_InvalidateByAddrCallback() should be implemented in the user file */ } /** * @brief Cache clean and Invalidate command by address callback. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval None */ __weak void HAL_DCACHE_CleanAndInvalidateByAddrCallback(DCACHE_HandleTypeDef *hdcache) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdcache); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DCACHE_CleanAndInvalidateByAddrCallback() should be implemented in the user file */ } /** * @brief Cache full invalidation complete callback. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval None */ __weak void HAL_DCACHE_InvalidateCompleteCallback(DCACHE_HandleTypeDef *hdcache) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdcache); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DCACHE_InvalidateCompleteCallback() should be implemented in the user file */ } /** * @brief Error callback. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval None */ __weak void HAL_DCACHE_ErrorCallback(DCACHE_HandleTypeDef *hdcache) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdcache); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DCACHE_ErrorCallback() should be implemented in the user file */ } /** * @} */ /** @defgroup DCACHE_Exported_Functions_Group3 Peripheral State, * @brief Peripheral State, * @verbatim =============================================================================== ##### Peripheral State ##### =============================================================================== [..] This subsection permit to get in run-time the status of the peripheral and the data flow. @endverbatim * @{ */ /** * @brief Return the DCACHE handle state. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @retval HAL state */ HAL_DCACHE_StateTypeDef HAL_DCACHE_GetState(DCACHE_HandleTypeDef *hdcache) { /* Return DCACHE handle state */ return hdcache->State; } /** * @} */ /** * @brief Return the DCACHE error code * @param hdcache pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHE. * @retval DCACHE Error Code */ uint32_t HAL_DCACHE_GetError(DCACHE_HandleTypeDef *hdcache) { /* Return DCACHE handle error code */ return hdcache->ErrorCode; } /** * @} */ /** * @} */ /** @addtogroup DCACHE_Exported_Functions * @{ */ /** @addtogroup DCACHE_Exported_Functions_Group1 * @{ */ /** * @brief Register a User DCACHE Callback * To be used instead of the weak predefined callback * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param CallbackID ID of the callback to be registered * This parameter can be one of the following values: * @arg @ref HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID Clean By Addr callback ID * @arg @ref HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID Invalidate By Addr callback ID * @arg @ref HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID Clean and Invalidate By Addr callback ID * @arg @ref HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID Invalidate Complete ID * @arg @ref HAL_DCACHE_ERROR_CB_ID Error callback ID * @arg @ref HAL_DCACHE_MSPINIT_CB_ID MspInit callback ID * @arg @ref HAL_DCACHE_MSPDEINIT_CB_ID MspDeInit callback ID * @param pCallback pointer to the Callback function * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_RegisterCallback(DCACHE_HandleTypeDef *hdcache, HAL_DCACHE_CallbackIDTypeDef CallbackID, pDCACHE_CallbackTypeDef pCallback) { HAL_StatusTypeDef status = HAL_OK; if (pCallback == NULL) { /* Update the error code */ hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; /* Return error status */ return HAL_ERROR; } if (hdcache->State == HAL_DCACHE_STATE_READY) { switch (CallbackID) { case HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID : hdcache->CleanByAddrCallback = pCallback; break; case HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID : hdcache->InvalidateByAddrCallback = pCallback; break; case HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID : hdcache->CleanAndInvalidateByAddrCallback = pCallback; break; case HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID : hdcache->InvalidateCompleteCallback = pCallback; break; case HAL_DCACHE_ERROR_CB_ID : hdcache->ErrorCallback = pCallback; break; case HAL_DCACHE_MSPINIT_CB_ID : hdcache->MspInitCallback = pCallback; break; case HAL_DCACHE_MSPDEINIT_CB_ID : hdcache->MspDeInitCallback = pCallback; break; default : /* Update the error code */ hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; break; } } else if (hdcache->State == HAL_DCACHE_STATE_RESET) { switch (CallbackID) { case HAL_DCACHE_MSPINIT_CB_ID : hdcache->MspInitCallback = pCallback; break; case HAL_DCACHE_MSPDEINIT_CB_ID : hdcache->MspDeInitCallback = pCallback; break; default : /* Update the error code */ hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; break; } } else { /* Update the error code */ hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; } return status; } /** * @brief Unregister an DCACHE Callback * DCACHE callback is redirected to the weak predefined callback * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param CallbackID ID of the callback to be unregistered * This parameter can be one of the following values: * @arg @ref HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID Clean By Addr callback ID * @arg @ref HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID Invalidate By Addr callback ID * @arg @ref HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID Clean and Invalidate By Addr callback ID * @arg @ref HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID Invalidate Complete callback ID * @arg @ref HAL_DCACHE_ERROR_CB_ID Error callback ID * @arg @ref HAL_DCACHE_MSPINIT_CB_ID MspInit callback ID * @arg @ref HAL_DCACHE_MSPDEINIT_CB_ID MspDeInit callback ID * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_UnRegisterCallback(DCACHE_HandleTypeDef *hdcache, HAL_DCACHE_CallbackIDTypeDef CallbackID) { HAL_StatusTypeDef status = HAL_OK; if (hdcache->State == HAL_DCACHE_STATE_READY) { switch (CallbackID) { case HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID : /* Legacy weak Clean By Addr Callback */ hdcache->CleanByAddrCallback = HAL_DCACHE_CleanByAddrCallback; break; case HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID : /* Legacy weak Invalidate By Addr Callback */ hdcache->InvalidateByAddrCallback = HAL_DCACHE_InvalidateByAddrCallback; break; case HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID : /* Legacy weak Clean and Invalidate By Addr Callback */ hdcache->CleanAndInvalidateByAddrCallback = HAL_DCACHE_CleanAndInvalidateByAddrCallback; break; case HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID : /* Legacy weak Invalidate Complete Callback */ hdcache->InvalidateCompleteCallback = HAL_DCACHE_InvalidateCompleteCallback; break; case HAL_DCACHE_ERROR_CB_ID : /* Legacy weak ErrorCallback */ hdcache->ErrorCallback = HAL_DCACHE_ErrorCallback; break; case HAL_DCACHE_MSPINIT_CB_ID : /* Legacy weak MspInit */ hdcache->MspInitCallback = HAL_DCACHE_MspInit; break; case HAL_DCACHE_MSPDEINIT_CB_ID : /* Legacy weak MspDeInit */ hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit; break; default : /* Update the error code */ hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; break; } } else if (HAL_DCACHE_STATE_RESET == hdcache->State) { switch (CallbackID) { case HAL_DCACHE_MSPINIT_CB_ID : /* Legacy weak MspInit */ hdcache->MspInitCallback = HAL_DCACHE_MspInit; break; case HAL_DCACHE_MSPDEINIT_CB_ID : /* Legacy weak MspDeInit */ hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit; break; default : /* Update the error code */ hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; break; } } else { /* Update the error code */ hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; } return status; } /** * @brief Start the Data Cache performance monitoring. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param MonitorType Monitoring type * This parameter can be a combination of the following values: * @arg DCACHE_MONITOR_READ_HIT * @arg DCACHE_MONITOR_READ_MISS * @arg DCACHE_MONITOR_WRITE_HIT * @arg DCACHE_MONITOR_WRITE_MISS * @arg DCACHE_MONITOR_ALL * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_Monitor_Start(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType) { /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType)); SET_BIT(hdcache->Instance->CR, MonitorType); return HAL_OK; } /** * @brief Stop the Data Cache performance monitoring. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @note Stopping the monitoring does not reset the values. * @param MonitorType Monitoring type * This parameter can be a combination of the following values: * @arg DCACHE_MONITOR_READ_HIT * @arg DCACHE_MONITOR_READ_MISS * @arg DCACHE_MONITOR_WRITE_HIT * @arg DCACHE_MONITOR_WRITE_MISS * @arg DCACHE_MONITOR_ALL * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_Monitor_Stop(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType) { /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType)); CLEAR_BIT(hdcache->Instance->CR, MonitorType); return HAL_OK; } /** * @brief Reset the Data Cache performance monitoring values. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param MonitorType Monitoring type * This parameter can be a combination of the following values: * @arg DCACHE_MONITOR_READ_HIT * @arg DCACHE_MONITOR_READ_MISS * @arg DCACHE_MONITOR_WRITE_HIT * @arg DCACHE_MONITOR_WRITE_MISS * @arg DCACHE_MONITOR_ALL * @retval HAL status */ HAL_StatusTypeDef HAL_DCACHE_Monitor_Reset(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType) { /* Check the dcache handle allocation */ if (hdcache == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType)); /* Force/Release reset */ SET_BIT(hdcache->Instance->CR, (MonitorType << 2U)); CLEAR_BIT(hdcache->Instance->CR, (MonitorType << 2U)); return HAL_OK; } /** * @brief Get the Data Cache performance Read Hit monitoring value. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @note Upon reaching the maximum value, monitor does not wrap. * @retval Read Hit monitoring value */ uint32_t HAL_DCACHE_Monitor_GetReadHitValue(DCACHE_HandleTypeDef *hdcache) { /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /*return the Read Hit monitor value*/ return hdcache->Instance->RHMONR; } /** * @brief Get the Data Cache performance Read Miss monitoring value. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @note Upon reaching the maximum value, monitor does not wrap. * @retval Read Miss monitoring value */ uint32_t HAL_DCACHE_Monitor_GetReadMissValue(DCACHE_HandleTypeDef *hdcache) { /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /*return the Read Miss monitor value*/ return hdcache->Instance->RMMONR; } /** * @brief Get the Data Cache performance Write Hit monitoring value. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @note Upon reaching the maximum value, monitor does not wrap. * @retval Write Hit monitoring value */ uint32_t HAL_DCACHE_Monitor_GetWriteHitValue(DCACHE_HandleTypeDef *hdcache) { /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /*return the Write Hit monitor value*/ return hdcache->Instance->WHMONR; } /** * @brief Get the Data Cache performance Write Miss monitoring value. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @note Upon reaching the maximum value, monitor does not wrap. * @retval Write Miss monitoring value */ uint32_t HAL_DCACHE_Monitor_GetWriteMissValue(DCACHE_HandleTypeDef *hdcache) { /* Check the parameters */ assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); /*return the Write Miss monitor value*/ return hdcache->Instance->WMMONR; } /** * @} */ /** * @brief launch dcache command Clean, Invalidate or clean and invalidate by Addr. * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains * the configuration information for the specified DCACHEx peripheral. * @param Command command to be applied for the dcache * DCACHE_COMMAND_INVALIDATE, DCACHE_COMMAND_CLEAN, DCACHE_COMMAND_CLEAN_INVALIDATE * @param pAddr Start address of region to be Cleaned, Invalidated or Cleaned and Invalidated. * @param dSize Size of the region to be Cleaned, Invalidated or Cleaned and Invalidated (in bytes). * @param mode mode to be applied for the dcache * DCACHE_IT_MODE, DCACHE_POLLING_MODE. * @retval HAL status */ static HAL_StatusTypeDef DCACHE_CommandByAddr(DCACHE_HandleTypeDef *hdcache, uint32_t Command, const uint32_t *const pAddr, uint32_t dSize, uint32_t mode) { HAL_StatusTypeDef status = HAL_OK; uint32_t op_addr = (uint32_t)pAddr; uint32_t tickstart; /* Check no ongoing operation */ if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) { /* Return busy status */ status = HAL_BUSY; } else { /* Update the error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; /* Update the DCACHE handle State */ hdcache->State = HAL_DCACHE_STATE_READY; /* Make sure flags are reset */ WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF)); /* Fill area start address */ WRITE_REG(hdcache->Instance->CMDRSADDRR, op_addr); /* Fill area end address */ WRITE_REG(hdcache->Instance->CMDREADDRR, (op_addr + dSize - 1U)); /* Set command */ MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, Command); /* Enable IT if required */ if (mode == DCACHE_IT_MODE) { /* Enable end of cache command interrupt */ SET_BIT(hdcache->Instance->IER, DCACHE_IER_CMDENDIE); /* Launch cache command */ SET_BIT(hdcache->Instance->CR, DCACHE_CR_STARTCMD); } else { /* Make sure that end of cache command interrupt is disabled */ CLEAR_BIT(hdcache->Instance->IER, DCACHE_IER_CMDENDIE); /* Launch cache command */ SET_BIT(hdcache->Instance->CR, DCACHE_CR_STARTCMD); /* Get timeout */ tickstart = HAL_GetTick(); /* Wait for end of cache command */ while (READ_BIT(hdcache->Instance->SR, DCACHE_SR_CMDENDF) == 0U) { if ((HAL_GetTick() - tickstart) > DCACHE_COMMAND_TIMEOUT_VALUE) { if (READ_BIT(hdcache->Instance->SR, DCACHE_SR_CMDENDF) == 0U) { /* Update error code */ hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT; /* Change the DCACHE state */ hdcache->State = HAL_DCACHE_STATE_ERROR; /* Return error status */ status = HAL_ERROR; break; } } } } } return status; } #endif /* HAL_DCACHE_MODULE_ENABLED */ /** * @} */ /** * @} */ /** * @} */