1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_hal_dcache.c
4   * @author  MCD Application Team
5   * @brief   DCACHE HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the DCACHE.
8   *           + Initialization and Configuration
9   *           + Cache coherency command
10   *           + Monitoring management
11   ******************************************************************************
12     * @attention
13   *
14   * Copyright (c) 2022 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23  ===============================================================================
24                         ##### How to use this driver #####
25  ===============================================================================
26   [..]
27    (#) Configure and enable the MPU to override default config if needed, please refers
28        to ARM manual for default memory attribute. Then enable DCache.
29 
30     [..]
31         (+) Use HAL_DCACHE_Invalidate() to invalidate the full cache content:
32             (++) Cache content is lost, and reloaded when needed.
33             (++) Used for complete invalidate of the dcache in case.
34             (++) Blocking call until operation is done.
35         (+) Use HAL_DCACHE_InvalidateByAddr() to invalidate cache content for specific range:
36             (++) Cache content for specific range is lost, and reloaded when needed.
37             (++) Used when excepting a buffer to be updated by a peripheral (typically DMA transfer)
38             (++) Blocking call until operation is done.
39         (+) Use HAL_DCACHE_CleanByAddr() to clean cache content for a specific range:
40             (++) Cache content for specific range is written back to memory.
41             (++) Used when buffer is updated by CPU before usage by a peripheral (typically DMA transfer)
42             (++) Blocking call until operation is done.
43         (+) Use HAL_DCACHE_CleanInvalidateByAddr() to clean and invalidate cache content for a specific range:
44             (++) Cache content for specific range is written back to memory, and reloaded when needed.
45             (++) Used when sharing buffer between CPU and other peripheral.
46             (++) Recommended to use for MPU reprogramming.
47             (++) Blocking call until operation is done.
48 
49      *** Interrupt mode IO operation ***
50      ===================================
51     [..]
52         (+) Configure the DCACHE interrupt priority using HAL_NVIC_SetPriority()
53         (+) Enable the DCACHE IRQ handler using HAL_NVIC_EnableIRQ()
54         (+) Override weak definition for following callback (if needed):
55             (++)HAL_DCACHE_CleanAndInvalidateByAddrCallback()
56             (++)HAL_DCACHE_InvalidateCompleteCallback()
57             (++)HAL_DCACHE_InvalidateByAddrCallback()
58             (++)HAL_DCACHE_CleanByAddrCallback()
59             (++)HAL_DCACHE_ErrorCallback()
60         (+) Use HAL_DCACHE_<COMMAND>_IT() to start a DCache operation with IT enabled.
61         (+) Use HAL_DCACHE_IRQHandler() called under DCACHE_IRQHandler() Interrupt subroutine
62 
63     [..]  Use HAL_DCACHE_GetState() function to return the DCACHE state and HAL_DCACHE_GetError()
64           in case of error detection.
65 
66      *** DCACHE HAL driver macros list ***
67      =============================================
68      [..]
69        Below the list of most used macros in DCACHE HAL driver.
70 
71       (+) __HAL_DCACHE_ENABLE_IT    : Enable DCACHE interrupts.
72       (+) __HAL_DCACHE_DISABLE_IT   : Disable DCACHE interrupts.
73       (+) __HAL_DCACHE_GET_IT_SOURCE: Check whether the specified DCACHE interrupt source is enabled or not.
74       (+) __HAL_DCACHE_GET_FLAG     : Check whether the selected DCACHE flag is set or not.
75       (+) __HAL_DCACHE_CLEAR_FLAG   : Clear the selected DCACHE flags.
76 
77      [..]
78       (@) You can refer to the header file of the DCACHE HAL driver for more useful macros.
79 
80     [..]
81 
82   @endverbatim
83   ******************************************************************************
84   */
85 
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32h5xx_hal.h"
88 
89 /** @addtogroup STM32H5xx_HAL_Driver
90   * @{
91   */
92 
93 /** @defgroup DCACHE DCACHE
94   * @brief HAL DCACHE module driver
95   * @{
96   */
97 #ifdef HAL_DCACHE_MODULE_ENABLED
98 
99 /* Private define ------------------------------------------------------------*/
100 /* Private macro -------------------------------------------------------------*/
101 /** @defgroup DCACHE_Private_Macros DCACHE Private Macros
102   * @{
103   */
104 #define IS_DCACHE_REGION_SIZE(__SIZE__)                ((__SIZE__) > 0U)
105 
106 #define IS_DCACHE_MONITOR_TYPE(__TYPE__)               (((__TYPE__) & ~DCACHE_MONITOR_ALL) == 0U)
107 
108 #define IS_DCACHE_SINGLE_MONITOR_TYPE(__TYPE__)        (((__TYPE__) == DCACHE_MONITOR_READ_HIT)  || \
109                                                         ((__TYPE__) == DCACHE_MONITOR_READ_MISS) || \
110                                                         ((__TYPE__) == DCACHE_MONITOR_WRITE_HIT) || \
111                                                         ((__TYPE__) == DCACHE_MONITOR_WRITE_MISS))
112 
113 #define IS_DCACHE_READ_BURST_TYPE(__OUTPUTBURSTTYPE__) (((__OUTPUTBURSTTYPE__) == DCACHE_READ_BURST_WRAP) || \
114                                                         ((__OUTPUTBURSTTYPE__) == DCACHE_READ_BURST_INCR))
115 
116 /**
117   * @}
118   */
119 
120 /* Private typedef -----------------------------------------------------------*/
121 /* Private constants ---------------------------------------------------------*/
122 /** @addtogroup DCACHE_Private_Constants DCACHE Private Constants
123   * @{
124   */
125 #define DCACHE_COMMAND_TIMEOUT_VALUE           200U    /* 200ms*/
126 #define DCACHE_DISABLE_TIMEOUT_VALUE           1U      /* 1ms  */
127 
128 #define DCACHE_COMMAND_INVALIDATE              DCACHE_CR_CACHECMD_1
129 #define DCACHE_COMMAND_CLEAN                   DCACHE_CR_CACHECMD_0
130 #define DCACHE_COMMAND_CLEAN_INVALIDATE        (DCACHE_CR_CACHECMD_0|DCACHE_CR_CACHECMD_1)
131 
132 #define DCACHE_POLLING_MODE                    0U
133 #define DCACHE_IT_MODE                         1U
134 
135 /**
136   * @}
137   */
138 
139 /* Private variables ---------------------------------------------------------*/
140 /* Private function prototypes -----------------------------------------------*/
141 static HAL_StatusTypeDef DCACHE_CommandByAddr(DCACHE_HandleTypeDef *hdcache, uint32_t Command,
142                                               const uint32_t *const pAddr, uint32_t dSize, uint32_t mode);
143 
144 /* Exported functions --------------------------------------------------------*/
145 /** @defgroup DCACHE_Exported_Functions DCACHE Exported Functions
146   * @{
147   */
148 
149 /** @defgroup DCACHE_Exported_Functions_Group1 Initialization and de-initialization functions
150   *  @brief    Initialization and Configuration functions
151   *
152 @verbatim
153  ===============================================================================
154               ##### Initialization and de-initialization functions #####
155  ===============================================================================
156     [..]  This subsection provides a set of functions allowing to initialize and
157           deinitialize the DCACHEx peripheral:
158 
159       (+) User must implement HAL_DCACHE_MspInit() function in which he configures
160           all related peripherals resources (CLOCK, MPU, IT and NVIC ).
161 
162       (+) Call the function HAL_DCACHE_Init() to configure the selected device with
163           the selected configuration:
164         (++) ReadBurstType
165 
166       (+) Call the function HAL_DCACHE_DeInit() to restore the reset configuration
167           of the selected DCACHEx peripheral.
168 
169 @endverbatim
170   * @{
171   */
172 
173 /**
174   * @brief  Initializes the DCACHE according to the specified parameters
175   *         in the DCACHE_InitTypeDef and initialize the associated handle.
176   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
177   *                 the configuration information for the specified DCACHE.
178   * @retval HAL status
179   */
HAL_DCACHE_Init(DCACHE_HandleTypeDef * hdcache)180 HAL_StatusTypeDef  HAL_DCACHE_Init(DCACHE_HandleTypeDef *hdcache)
181 {
182   HAL_StatusTypeDef status;
183 
184   /* Check the DCACHE handle allocation */
185   if (hdcache == NULL)
186   {
187     return HAL_ERROR;
188   }
189 
190   /* Check the parameters */
191   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
192   assert_param(IS_DCACHE_READ_BURST_TYPE(hdcache->Init.ReadBurstType));
193 
194   if (hdcache->State == HAL_DCACHE_STATE_RESET)
195   {
196     /* Init the DCACHE Callback settings with legacy weak */
197     hdcache->ErrorCallback                      = HAL_DCACHE_ErrorCallback;
198     hdcache->CleanByAddrCallback                = HAL_DCACHE_CleanByAddrCallback;
199     hdcache->InvalidateByAddrCallback           = HAL_DCACHE_InvalidateByAddrCallback;
200     hdcache->InvalidateCompleteCallback         = HAL_DCACHE_InvalidateCompleteCallback;
201     hdcache->CleanAndInvalidateByAddrCallback   = HAL_DCACHE_CleanAndInvalidateByAddrCallback;
202 
203     if (hdcache->MspInitCallback == NULL)
204     {
205       hdcache->MspInitCallback = HAL_DCACHE_MspInit;
206     }
207 
208     /* Init the low level hardware */
209     hdcache->MspInitCallback(hdcache);
210   }
211 
212   /* Init the error code */
213   hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE;
214 
215   /* Init the DCACHE handle state */
216   hdcache->State = HAL_DCACHE_STATE_READY;
217 
218   /* Set requested read burst type */
219   MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_HBURST, hdcache->Init.ReadBurstType);
220 
221   /* Enable the selected DCACHE peripheral */
222   status = HAL_DCACHE_Enable(hdcache);
223 
224   return status;
225 }
226 
227 /**
228   * @brief  DeInitialize the Data cache.
229   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
230   *                 the configuration information for the specified DCACHEx peripheral.
231   * @retval HAL status
232   */
HAL_DCACHE_DeInit(DCACHE_HandleTypeDef * hdcache)233 HAL_StatusTypeDef HAL_DCACHE_DeInit(DCACHE_HandleTypeDef *hdcache)
234 {
235   HAL_StatusTypeDef status;
236 
237   /* Check the dcache handle allocation */
238   if (hdcache == NULL)
239   {
240     return HAL_ERROR;
241   }
242 
243   /* Check the parameters */
244   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
245 
246   /* Update the error code */
247   hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE;
248 
249   /* Return to the reset state */
250   hdcache->State = HAL_DCACHE_STATE_RESET;
251 
252   /* Disable cache */
253   status = HAL_DCACHE_Disable(hdcache);
254 
255   /* reset monitor values */
256   (void)HAL_DCACHE_Monitor_Reset(hdcache, DCACHE_MONITOR_ALL);
257 
258   /* Reset all remaining bit */
259   WRITE_REG(hdcache->Instance->CR, 0U);
260   WRITE_REG(hdcache->Instance->CMDRSADDRR, 0U);
261   WRITE_REG(hdcache->Instance->CMDREADDRR, 0U);
262   WRITE_REG(hdcache->Instance->FCR, DCACHE_FCR_CCMDENDF | DCACHE_FCR_CERRF | DCACHE_FCR_CBSYENDF);
263 
264   if (hdcache->MspDeInitCallback == NULL)
265   {
266     hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit;
267   }
268 
269   /* DeInit the low level hardware */
270   hdcache->MspDeInitCallback(hdcache);
271 
272   return status;
273 }
274 
275 /**
276   * @brief Initialize the DCACHE MSP.
277   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
278   *                 the configuration information for the specified DCACHEx peripheral.
279   * @retval None
280   */
HAL_DCACHE_MspInit(DCACHE_HandleTypeDef * hdcache)281 __weak void HAL_DCACHE_MspInit(DCACHE_HandleTypeDef *hdcache)
282 {
283   /* Prevent unused argument(s) compilation warning */
284   UNUSED(hdcache);
285 
286   /* NOTE : This function should not be modified, when the callback is needed,
287             the HAL_DCACHE_MspInit can be implemented in the user file
288    */
289 }
290 
291 /**
292   * @brief DeInitialize the DCACHE MSP.
293   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
294   *                 the configuration information for the specified DCACHEx peripheral.
295   * @retval None
296   */
HAL_DCACHE_MspDeInit(DCACHE_HandleTypeDef * hdcache)297 __weak void HAL_DCACHE_MspDeInit(DCACHE_HandleTypeDef *hdcache)
298 {
299   /* Prevent unused argument(s) compilation warning */
300   UNUSED(hdcache);
301 
302   /* NOTE : This function should not be modified, when the callback is needed,
303             the HAL_DCACHE_MspDeInit can be implemented in the user file
304    */
305 }
306 
307 /** @defgroup DCACHE_Exported_Functions_Group2 IO operation functions
308   *  @brief    IO operation functions
309   *
310 @verbatim
311   ==============================================================================
312              ##### IO operation functions #####
313   ==============================================================================
314     [..]  This section provides functions allowing to:
315       (+) Enable the Data cache.
316       (+) Disable the Data cache.
317       (+) Set Read Burst Type.
318       (+) Invalidate the Data cache.
319       (+) Invalidate the Data cache with interrupt.
320       (+) Clean the Data cache by Addr.
321       (+) Invalidate the Data cache by Addr.
322       (+) Clean and Invalidate the Data cache by Addr.
323       (+) Clean the Data cache by Addr with interrupt.
324       (+) Invalidate the Data cache by Addr with interrupt.
325       (+) Clean and Invalidate the Data cache by Addr with interrupt.
326 @endverbatim
327   * @{
328   */
329 
330 /**
331   * @brief  Enable the Data cache.
332   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
333   *                 the configuration information for the specified DCACHEx peripheral.
334   * @retval HAL status
335   */
HAL_DCACHE_Enable(DCACHE_HandleTypeDef * hdcache)336 HAL_StatusTypeDef HAL_DCACHE_Enable(DCACHE_HandleTypeDef *hdcache)
337 {
338   HAL_StatusTypeDef status = HAL_OK;
339 
340   /* Check the dcache handle allocation */
341   if (hdcache == NULL)
342   {
343     return HAL_ERROR;
344   }
345 
346   /* Check the parameters */
347   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
348 
349   /* Check no ongoing operation */
350   if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U)
351   {
352     /* Return busy status */
353     status =  HAL_BUSY;
354   }
355   else
356   {
357     /* Update the error code */
358     hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE;
359 
360     /* Enable the selected DCACHE peripheral */
361     SET_BIT(hdcache->Instance->CR, DCACHE_CR_EN);
362   }
363 
364   return status;
365 }
366 
367 /**
368   * @brief  Disable the Data cache.
369   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
370   *                 the configuration information for the specified DCACHEx peripheral.
371   * @retval HAL status
372   */
HAL_DCACHE_Disable(DCACHE_HandleTypeDef * hdcache)373 HAL_StatusTypeDef HAL_DCACHE_Disable(DCACHE_HandleTypeDef *hdcache)
374 {
375   HAL_StatusTypeDef status = HAL_OK;
376 
377   uint32_t tickstart;
378 
379   /* Check the dcache handle allocation */
380   if (hdcache == NULL)
381   {
382     return HAL_ERROR;
383   }
384 
385   /* Check the parameters */
386   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
387 
388   /* Check DCACHE handle status */
389   if (HAL_DCACHE_IsEnabled(hdcache) != 0U)
390   {
391     /* Update the error code */
392     hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE;
393 
394     /* Change DCACHE handle state */
395     hdcache->State = HAL_DCACHE_STATE_READY;
396 
397     /* Disable the selected DCACHE peripheral */
398     CLEAR_BIT(hdcache->Instance->CR, DCACHE_CR_EN);
399 
400     /* Get timeout */
401     tickstart = HAL_GetTick();
402 
403     /* Wait for end of data cache disabling */
404     while (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U)
405     {
406       if ((HAL_GetTick() - tickstart) > DCACHE_DISABLE_TIMEOUT_VALUE)
407       {
408         if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U)
409         {
410           /* Update error code */
411           hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT;
412 
413           /* Change the DCACHE handle state */
414           hdcache->State = HAL_DCACHE_STATE_ERROR;
415 
416           /* Return error status */
417           status =  HAL_ERROR;
418           break;
419         }
420       }
421     }
422   }
423 
424   return status;
425 }
426 /**
427   * @brief  Check whether the Data Cache is enabled or not.
428   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
429   *                 the configuration information for the specified DCACHEx peripheral.
430   * @retval Status (0: disabled, 1: enabled)
431   */
HAL_DCACHE_IsEnabled(DCACHE_HandleTypeDef * hdcache)432 uint32_t HAL_DCACHE_IsEnabled(DCACHE_HandleTypeDef *hdcache)
433 {
434   return ((READ_BIT(hdcache->Instance->CR, DCACHE_CR_EN) != 0U) ? 1UL : 0UL);
435 }
436 
437 /**
438   * @brief  Set Read Burst Type.
439   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
440   *                 the configuration information for the specified DCACHEx peripheral.
441   * @param  ReadBurstType Burst type to be applied for Data Cache
442   *                       DCACHE_READ_BURST_WRAP, DCACHE_READ_BURST_INC.
443   * @retval HAL status
444   */
HAL_DCACHE_SetReadBurstType(DCACHE_HandleTypeDef * hdcache,uint32_t ReadBurstType)445 HAL_StatusTypeDef HAL_DCACHE_SetReadBurstType(DCACHE_HandleTypeDef *hdcache, uint32_t ReadBurstType)
446 {
447   HAL_StatusTypeDef status = HAL_OK;
448 
449   /* Check the dcache handle allocation */
450   if (hdcache == NULL)
451   {
452     return HAL_ERROR;
453   }
454 
455   /* Check the parameters */
456   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
457   assert_param(IS_DCACHE_READ_BURST_TYPE(ReadBurstType));
458 
459   /* check DCACHE status */
460   if (HAL_DCACHE_IsEnabled(hdcache) == 0U)
461   {
462     /* Set requested read burst type */
463     MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_HBURST, ReadBurstType);
464   }
465   else
466   {
467     /* Update the error code */
468     hdcache->ErrorCode = HAL_DCACHE_ERROR_INVALID_OPERATION;
469 
470     /* Return error status */
471     status =  HAL_ERROR;
472   }
473 
474   return status;
475 }
476 
477 /**
478   * @brief  Invalidate the Data cache.
479   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
480   *                 the configuration information for the specified DCACHEx peripheral.
481   * @note   This function waits for end of full cache invalidation
482   * @retval HAL status
483   */
HAL_DCACHE_Invalidate(DCACHE_HandleTypeDef * hdcache)484 HAL_StatusTypeDef HAL_DCACHE_Invalidate(DCACHE_HandleTypeDef *hdcache)
485 {
486   HAL_StatusTypeDef status = HAL_OK;
487   uint32_t tickstart;
488 
489   /* Check the dcache handle allocation */
490   if (hdcache == NULL)
491   {
492     return HAL_ERROR;
493   }
494 
495   /* Check the parameters */
496   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
497 
498   /* Check no ongoing operation */
499   if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U)
500   {
501     /* Return busy status */
502     status =  HAL_BUSY;
503   }
504   else
505   {
506     /* Update the error code */
507     hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE;
508 
509     /* Change DCACHE Handle state */
510     hdcache->State = HAL_DCACHE_STATE_READY;
511 
512     /* Make sure flags are reset */
513     WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF));
514 
515     /* Set no operation on address range */
516     MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, 0U);
517 
518     /* Launch cache invalidation */
519     SET_BIT(hdcache->Instance->CR, DCACHE_CR_CACHEINV);
520 
521     /* Get timeout */
522     tickstart = HAL_GetTick();
523 
524     /* Wait for end of cache invalidation */
525     while (READ_BIT(hdcache->Instance->SR, DCACHE_SR_BUSYF) != 0U)
526     {
527       if ((HAL_GetTick() - tickstart) > DCACHE_COMMAND_TIMEOUT_VALUE)
528       {
529         if (READ_BIT(hdcache->Instance->SR, DCACHE_SR_BUSYF) != 0U)
530         {
531           /* Update error code */
532           hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT;
533 
534           /* Change the DCACHE state */
535           hdcache->State = HAL_DCACHE_STATE_ERROR;
536 
537           /* Return error status */
538           status =  HAL_ERROR;
539           break;
540         }
541       }
542     }
543   }
544 
545   return status;
546 }
547 
548 /**
549   * @brief  Invalidate the Data cache for a specific region.
550   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
551   *                 the configuration information for the specified DCACHEx peripheral.
552   * @param  pAddr Start address of the region to be Invalidated
553   * @param  dSize Size of the region to be Invalidated(in bytes)
554   * @note   This function waits for end of cache Invalidation
555   * @retval HAL status
556   */
HAL_DCACHE_InvalidateByAddr(DCACHE_HandleTypeDef * hdcache,const uint32_t * const pAddr,uint32_t dSize)557 HAL_StatusTypeDef HAL_DCACHE_InvalidateByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr,
558                                               uint32_t dSize)
559 {
560   HAL_StatusTypeDef status;
561 
562   /* Check the dcache handle allocation */
563   if (hdcache == NULL)
564   {
565     return HAL_ERROR;
566   }
567 
568   /* Check the parameters */
569   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
570   assert_param(IS_DCACHE_REGION_SIZE(dSize));
571 
572   status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_INVALIDATE, pAddr, dSize, DCACHE_POLLING_MODE);
573 
574   return status;
575 }
576 
577 /**
578   * @brief  Clean the Data cache by Addr.
579   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
580   *                 the configuration information for the specified DCACHEx peripheral.
581   * @param  pAddr Start address of the region to be Cleaned
582   * @param  dSize Size of the region to be Cleaned (in bytes)
583   * @note   This function waits for end of cache Clean
584   * @retval HAL status
585   */
HAL_DCACHE_CleanByAddr(DCACHE_HandleTypeDef * hdcache,const uint32_t * const pAddr,uint32_t dSize)586 HAL_StatusTypeDef HAL_DCACHE_CleanByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize)
587 {
588   HAL_StatusTypeDef status;
589 
590   /* Check the dcache handle allocation */
591   if (hdcache == NULL)
592   {
593     return HAL_ERROR;
594   }
595 
596   /* Check the parameters */
597   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
598   assert_param(IS_DCACHE_REGION_SIZE(dSize));
599 
600   status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN, pAddr, dSize, DCACHE_POLLING_MODE);
601 
602   return status;
603 }
604 
605 /**
606   * @brief  Clean and Invalidate the Data cache by Addr.
607   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
608   *                 the configuration information for the specified DCACHEx peripheral.
609   * @param  pAddr Start address of the region to be Cleaned and Invalidated
610   * @param  dSize Size of the region to be Cleaned and Invalidated (in bytes)
611   * @note   This function waits for end of cache Clean and Invalidation
612   * @retval HAL status
613   */
HAL_DCACHE_CleanInvalidByAddr(DCACHE_HandleTypeDef * hdcache,const uint32_t * const pAddr,uint32_t dSize)614 HAL_StatusTypeDef HAL_DCACHE_CleanInvalidByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr,
615                                                 uint32_t dSize)
616 {
617   HAL_StatusTypeDef status;
618 
619   /* Check the dcache handle allocation */
620   if (hdcache == NULL)
621   {
622     return HAL_ERROR;
623   }
624 
625   /* Check the parameters */
626   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
627   assert_param(IS_DCACHE_REGION_SIZE(dSize));
628 
629   status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN_INVALIDATE, pAddr, dSize, DCACHE_POLLING_MODE);
630 
631   return status;
632 }
633 
634 /**
635   * @brief  Invalidate the Data cache with interrupt.
636   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
637   *                 the configuration information for the specified DCACHEx peripheral.
638   * @note   This function launches maintenance operation and returns immediately.
639   *         User application shall resort to interrupt generation to check
640   *         the end of operation.
641   * @retval HAL status
642   */
HAL_DCACHE_Invalidate_IT(DCACHE_HandleTypeDef * hdcache)643 HAL_StatusTypeDef HAL_DCACHE_Invalidate_IT(DCACHE_HandleTypeDef *hdcache)
644 {
645   HAL_StatusTypeDef status = HAL_OK;
646 
647   /* Check the dcache handle allocation */
648   if (hdcache == NULL)
649   {
650     return HAL_ERROR;
651   }
652 
653   /* Check the parameters */
654   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
655 
656   /* Check no ongoing operation */
657   if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U)
658   {
659     /* Return busy status */
660     status =  HAL_BUSY;
661   }
662   else
663   {
664     /* Update the error code */
665     hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE;
666 
667     /* Change DCACHE Handle state */
668     hdcache->State = HAL_DCACHE_STATE_READY;
669 
670     /* Make sure BSYENDF is reset */
671     WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF));
672 
673     /* Set no operation on address range for callback under interrupt */
674     MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, 0U);
675 
676     /* Enable end of cache invalidation interrupt */
677     SET_BIT(hdcache->Instance->IER, DCACHE_IER_BSYENDIE);
678 
679     /* Launch cache invalidation */
680     SET_BIT(hdcache->Instance->CR, DCACHE_CR_CACHEINV);
681   }
682 
683   return status;
684 }
685 
686 /**
687   * @brief  Invalidate the Data cache by Addr with interrupt.
688   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
689   *                 the configuration information for the specified DCACHEx peripheral.
690   * @param  pAddr Start address of the region to be Invalidated
691   * @param  dSize Size of the region to be Invalidated
692   * @note   This function launches maintenance operation and returns immediately.
693   *         User application shall resort to interrupt generation to check
694   *         the end of operation.
695   * @retval HAL status
696   */
HAL_DCACHE_InvalidateByAddr_IT(DCACHE_HandleTypeDef * hdcache,const uint32_t * const pAddr,uint32_t dSize)697 HAL_StatusTypeDef HAL_DCACHE_InvalidateByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr,
698                                                  uint32_t dSize)
699 {
700   HAL_StatusTypeDef status;
701 
702   /* Check the dcache handle allocation */
703   if (hdcache == NULL)
704   {
705     return HAL_ERROR;
706   }
707 
708   /* Check the parameters */
709   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
710   assert_param(IS_DCACHE_REGION_SIZE(dSize));
711 
712   status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_INVALIDATE, pAddr, dSize, DCACHE_IT_MODE);
713 
714   return status;
715 }
716 
717 /**
718   * @brief  Clean the Data cache by Addr with interrupt.
719   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
720   *                 the configuration information for the specified DCACHEx peripheral.
721   * @param  pAddr Start address of the region to be Cleaned
722   * @param  dSize Size of the region to be Cleaned
723   * @note   This function launches maintenance operation and returns immediately.
724   *         User application shall resort to interrupt generation to check
725   *         the end of operation.
726   * @retval HAL status
727   */
HAL_DCACHE_CleanByAddr_IT(DCACHE_HandleTypeDef * hdcache,const uint32_t * const pAddr,uint32_t dSize)728 HAL_StatusTypeDef HAL_DCACHE_CleanByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr,
729                                             uint32_t dSize)
730 {
731   HAL_StatusTypeDef status;
732 
733   /* Check the dcache handle allocation */
734   if (hdcache == NULL)
735   {
736     return HAL_ERROR;
737   }
738 
739   /* Check the parameters */
740   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
741   assert_param(IS_DCACHE_REGION_SIZE(dSize));
742 
743   status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN, pAddr, dSize, DCACHE_IT_MODE);
744 
745   return status;
746 }
747 
748 /**
749   * @brief  Clean and Invalidate the Data cache by Addr with interrupt.
750   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
751   *                 the configuration information for the specified DCACHEx peripheral.
752   * @param  pAddr Start address of the region to be Cleaned and Invalidated
753   * @param  dSize Size of the region to be Cleaned and Invalidated
754   * @note   This function launches maintenance operation and returns immediately.
755   *         User application shall resort to interrupt generation to check
756   *         the end of operation.
757   * @retval HAL status
758   */
HAL_DCACHE_CleanInvalidByAddr_IT(DCACHE_HandleTypeDef * hdcache,const uint32_t * const pAddr,uint32_t dSize)759 HAL_StatusTypeDef HAL_DCACHE_CleanInvalidByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr,
760                                                    uint32_t dSize)
761 {
762   HAL_StatusTypeDef status;
763 
764   /* Check the dcache handle allocation */
765   if (hdcache == NULL)
766   {
767     return HAL_ERROR;
768   }
769 
770   /* Check the parameters */
771   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
772   assert_param(IS_DCACHE_REGION_SIZE(dSize));
773 
774   status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN_INVALIDATE, pAddr, dSize, DCACHE_IT_MODE);
775 
776   return status;
777 }
778 
779 /**
780   * @brief Handle the Data Cache interrupt request.
781   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
782   *                 the configuration information for the specified DCACHEx peripheral.
783   * @note  This API should be called under the DCACHE_IRQHandler().
784   * @retval None
785   */
HAL_DCACHE_IRQHandler(DCACHE_HandleTypeDef * hdcache)786 void HAL_DCACHE_IRQHandler(DCACHE_HandleTypeDef *hdcache)
787 {
788   /* Get current interrupt flags and interrupt sources value */
789   uint32_t itflags   = READ_REG(hdcache->Instance->SR);
790   uint32_t itsources = READ_REG(hdcache->Instance->IER);
791 
792   /* Check the parameters */
793   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
794 
795   /* Check Data cache Error interrupt flag  */
796   if (((itflags & itsources) & DCACHE_FLAG_ERROR) != 0U)
797   {
798     /* Clear DCACHE error pending flag */
799     __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_ERROR);
800 
801     /* Update data cache error code */
802     hdcache->ErrorCode = HAL_DCACHE_ERROR_EVICTION_CLEAN;
803 
804     /* Data cache error interrupt user callback */
805     hdcache->ErrorCallback(hdcache);
806   }
807 
808   if (READ_BIT(hdcache->Instance->CR, DCACHE_CR_CACHECMD) == 0U) /* no operation by range */
809   {
810     /* Clear DCACHE busyend pending flag */
811     __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_BUSYEND);
812 
813     /* Data cache invalidate complete interrupt user callback */
814     hdcache->InvalidateCompleteCallback(hdcache);
815   }
816   else if (READ_BIT(hdcache->Instance->CR, DCACHE_CR_CACHECMD_1 | DCACHE_CR_CACHECMD_0) == \
817            (DCACHE_CR_CACHECMD_1 | DCACHE_CR_CACHECMD_0))
818   {
819     /* Clear DCACHE cmdend pending flag */
820     __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND);
821 
822     /* Data cache clean and invalidate range cmdend interrupt user callback */
823     hdcache->CleanAndInvalidateByAddrCallback(hdcache);
824   }
825   else if (READ_BIT(hdcache->Instance->CR, DCACHE_CR_CACHECMD_0) == DCACHE_CR_CACHECMD_0)
826   {
827     /* Clear DCACHE cmdend pending flag */
828     __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND);
829 
830     /* Data cache clean range cmdend interrupt user callback */
831     hdcache->CleanByAddrCallback(hdcache);
832   }
833   else
834   {
835     /* Clear DCACHE cmdend pending flag */
836     __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND);
837 
838     /* Data cache Invalidate range cmdend interrupt user callback */
839     hdcache->InvalidateByAddrCallback(hdcache);
840   }
841 }
842 
843 /**
844   * @brief  Cache clean  command  by address callback.
845   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
846   *                 the configuration information for the specified DCACHEx peripheral.
847   * @retval None
848   */
HAL_DCACHE_CleanByAddrCallback(DCACHE_HandleTypeDef * hdcache)849 __weak void HAL_DCACHE_CleanByAddrCallback(DCACHE_HandleTypeDef *hdcache)
850 {
851   /* Prevent unused argument(s) compilation warning */
852   UNUSED(hdcache);
853 
854   /* NOTE : This function should not be modified, when the callback is needed,
855             the HAL_DCACHE_CleanByAddrCallback() should be implemented in the user file
856    */
857 }
858 
859 /**
860   * @brief  Cache Invalidate  command  by address callback.
861   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
862   *                 the configuration information for the specified DCACHEx peripheral.
863   * @retval None
864   */
HAL_DCACHE_InvalidateByAddrCallback(DCACHE_HandleTypeDef * hdcache)865 __weak void HAL_DCACHE_InvalidateByAddrCallback(DCACHE_HandleTypeDef *hdcache)
866 {
867   /* Prevent unused argument(s) compilation warning */
868   UNUSED(hdcache);
869 
870   /* NOTE : This function should not be modified, when the callback is needed,
871             the HAL_DCACHE_InvalidateByAddrCallback() should be implemented in the user file
872    */
873 }
874 
875 /**
876   * @brief  Cache clean and Invalidate command  by address callback.
877   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
878   *                 the configuration information for the specified DCACHEx peripheral.
879   * @retval None
880   */
HAL_DCACHE_CleanAndInvalidateByAddrCallback(DCACHE_HandleTypeDef * hdcache)881 __weak void HAL_DCACHE_CleanAndInvalidateByAddrCallback(DCACHE_HandleTypeDef *hdcache)
882 {
883   /* Prevent unused argument(s) compilation warning */
884   UNUSED(hdcache);
885 
886   /* NOTE : This function should not be modified, when the callback is needed,
887             the HAL_DCACHE_CleanAndInvalidateByAddrCallback() should be implemented in the user file
888    */
889 }
890 
891 /**
892   * @brief  Cache full invalidation complete callback.
893   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
894   *                 the configuration information for the specified DCACHEx peripheral.
895   * @retval None
896   */
HAL_DCACHE_InvalidateCompleteCallback(DCACHE_HandleTypeDef * hdcache)897 __weak void HAL_DCACHE_InvalidateCompleteCallback(DCACHE_HandleTypeDef *hdcache)
898 {
899   /* Prevent unused argument(s) compilation warning */
900   UNUSED(hdcache);
901 
902   /* NOTE : This function should not be modified, when the callback is needed,
903             the HAL_DCACHE_InvalidateCompleteCallback() should be implemented in the user file
904    */
905 }
906 
907 /**
908   * @brief  Error callback.
909   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
910   *                 the configuration information for the specified DCACHEx peripheral.
911   * @retval None
912   */
HAL_DCACHE_ErrorCallback(DCACHE_HandleTypeDef * hdcache)913 __weak void HAL_DCACHE_ErrorCallback(DCACHE_HandleTypeDef *hdcache)
914 {
915   /* Prevent unused argument(s) compilation warning */
916   UNUSED(hdcache);
917 
918   /* NOTE : This function should not be modified, when the callback is needed,
919             the HAL_DCACHE_ErrorCallback() should be implemented in the user file
920    */
921 }
922 
923 /**
924   * @}
925   */
926 
927 /** @defgroup DCACHE_Exported_Functions_Group3 Peripheral State,
928   *  @brief   Peripheral State,
929   *
930 @verbatim
931  ===============================================================================
932             #####          Peripheral State          #####
933  ===============================================================================
934     [..]
935     This subsection permit to get in run-time the status of the peripheral
936     and the data flow.
937 
938 @endverbatim
939   * @{
940   */
941 
942 /**
943   * @brief  Return the DCACHE handle state.
944   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
945   *                 the configuration information for the specified DCACHEx peripheral.
946   * @retval HAL state
947   */
HAL_DCACHE_GetState(DCACHE_HandleTypeDef * hdcache)948 HAL_DCACHE_StateTypeDef HAL_DCACHE_GetState(DCACHE_HandleTypeDef *hdcache)
949 {
950   /* Return DCACHE handle state */
951   return hdcache->State;
952 }
953 
954 /**
955   * @}
956   */
957 
958 /**
959   * @brief  Return the DCACHE error code
960   * @param  hdcache pointer to a DCACHE_HandleTypeDef structure that contains
961   *         the configuration information for the specified DCACHE.
962   * @retval DCACHE Error Code
963   */
HAL_DCACHE_GetError(DCACHE_HandleTypeDef * hdcache)964 uint32_t HAL_DCACHE_GetError(DCACHE_HandleTypeDef *hdcache)
965 {
966   /* Return DCACHE handle error code */
967   return hdcache->ErrorCode;
968 }
969 
970 /**
971   * @}
972   */
973 
974 /**
975   * @}
976   */
977 
978 /** @addtogroup DCACHE_Exported_Functions
979   * @{
980   */
981 
982 /** @addtogroup DCACHE_Exported_Functions_Group1
983   * @{
984   */
985 
986 /**
987   * @brief  Register a User DCACHE Callback
988   *         To be used instead of the weak predefined callback
989   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
990   *                 the configuration information for the specified DCACHEx peripheral.
991   * @param  CallbackID ID of the callback to be registered
992   *         This parameter can be one of the following values:
993   *          @arg @ref HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID Clean By Addr callback ID
994   *          @arg @ref HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID Invalidate By Addr callback ID
995   *          @arg @ref HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID Clean and Invalidate By Addr callback ID
996   *          @arg @ref HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID Invalidate Complete ID
997   *          @arg @ref HAL_DCACHE_ERROR_CB_ID  Error callback ID
998   *          @arg @ref HAL_DCACHE_MSPINIT_CB_ID MspInit callback ID
999   *          @arg @ref HAL_DCACHE_MSPDEINIT_CB_ID MspDeInit callback ID
1000   * @param  pCallback pointer to the Callback function
1001   * @retval HAL status
1002   */
HAL_DCACHE_RegisterCallback(DCACHE_HandleTypeDef * hdcache,HAL_DCACHE_CallbackIDTypeDef CallbackID,pDCACHE_CallbackTypeDef pCallback)1003 HAL_StatusTypeDef HAL_DCACHE_RegisterCallback(DCACHE_HandleTypeDef *hdcache, HAL_DCACHE_CallbackIDTypeDef CallbackID,
1004                                               pDCACHE_CallbackTypeDef pCallback)
1005 {
1006   HAL_StatusTypeDef status = HAL_OK;
1007 
1008   if (pCallback == NULL)
1009   {
1010     /* Update the error code */
1011     hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK;
1012 
1013     /* Return error status */
1014     return HAL_ERROR;
1015   }
1016 
1017   if (hdcache->State == HAL_DCACHE_STATE_READY)
1018   {
1019     switch (CallbackID)
1020     {
1021       case HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID :
1022         hdcache->CleanByAddrCallback = pCallback;
1023         break;
1024 
1025       case HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID :
1026         hdcache->InvalidateByAddrCallback = pCallback;
1027         break;
1028 
1029       case HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID :
1030         hdcache->CleanAndInvalidateByAddrCallback = pCallback;
1031         break;
1032 
1033       case HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID :
1034         hdcache->InvalidateCompleteCallback = pCallback;
1035         break;
1036 
1037       case HAL_DCACHE_ERROR_CB_ID :
1038         hdcache->ErrorCallback = pCallback;
1039         break;
1040 
1041       case HAL_DCACHE_MSPINIT_CB_ID :
1042         hdcache->MspInitCallback = pCallback;
1043         break;
1044 
1045       case HAL_DCACHE_MSPDEINIT_CB_ID :
1046         hdcache->MspDeInitCallback = pCallback;
1047         break;
1048 
1049       default :
1050         /* Update the error code */
1051         hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK;
1052 
1053         /* Return error status */
1054         status =  HAL_ERROR;
1055         break;
1056     }
1057   }
1058   else if (hdcache->State == HAL_DCACHE_STATE_RESET)
1059   {
1060     switch (CallbackID)
1061     {
1062       case HAL_DCACHE_MSPINIT_CB_ID :
1063         hdcache->MspInitCallback = pCallback;
1064         break;
1065 
1066       case HAL_DCACHE_MSPDEINIT_CB_ID :
1067         hdcache->MspDeInitCallback = pCallback;
1068         break;
1069 
1070       default :
1071         /* Update the error code */
1072         hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK;
1073 
1074         /* Return error status */
1075         status =  HAL_ERROR;
1076         break;
1077     }
1078   }
1079   else
1080   {
1081     /* Update the error code */
1082     hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK;
1083 
1084     /* Return error status */
1085     status =  HAL_ERROR;
1086   }
1087 
1088   return status;
1089 }
1090 
1091 /**
1092   * @brief  Unregister an DCACHE Callback
1093   *         DCACHE callback is redirected to the weak predefined callback
1094   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1095   *                 the configuration information for the specified DCACHEx peripheral.
1096   * @param  CallbackID ID of the callback to be unregistered
1097   *         This parameter can be one of the following values:
1098   *          @arg @ref HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID Clean By Addr callback ID
1099   *          @arg @ref HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID Invalidate By Addr callback ID
1100   *          @arg @ref HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID Clean and Invalidate By Addr callback ID
1101   *          @arg @ref HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID Invalidate Complete callback ID
1102   *          @arg @ref HAL_DCACHE_ERROR_CB_ID  Error callback ID
1103   *          @arg @ref HAL_DCACHE_MSPINIT_CB_ID MspInit callback ID
1104   *          @arg @ref HAL_DCACHE_MSPDEINIT_CB_ID MspDeInit callback ID
1105   * @retval HAL status
1106   */
HAL_DCACHE_UnRegisterCallback(DCACHE_HandleTypeDef * hdcache,HAL_DCACHE_CallbackIDTypeDef CallbackID)1107 HAL_StatusTypeDef HAL_DCACHE_UnRegisterCallback(DCACHE_HandleTypeDef *hdcache, HAL_DCACHE_CallbackIDTypeDef CallbackID)
1108 {
1109   HAL_StatusTypeDef status = HAL_OK;
1110 
1111   if (hdcache->State == HAL_DCACHE_STATE_READY)
1112   {
1113     switch (CallbackID)
1114     {
1115       case HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID :
1116         /* Legacy weak Clean By Addr Callback */
1117         hdcache->CleanByAddrCallback = HAL_DCACHE_CleanByAddrCallback;
1118         break;
1119 
1120       case HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID :
1121         /* Legacy weak Invalidate By Addr Callback */
1122         hdcache->InvalidateByAddrCallback = HAL_DCACHE_InvalidateByAddrCallback;
1123         break;
1124 
1125       case HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID :
1126         /* Legacy weak Clean and Invalidate By Addr Callback */
1127         hdcache->CleanAndInvalidateByAddrCallback = HAL_DCACHE_CleanAndInvalidateByAddrCallback;
1128         break;
1129 
1130       case HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID :
1131         /* Legacy weak Invalidate Complete Callback */
1132         hdcache->InvalidateCompleteCallback = HAL_DCACHE_InvalidateCompleteCallback;
1133         break;
1134 
1135       case HAL_DCACHE_ERROR_CB_ID :
1136         /* Legacy weak ErrorCallback */
1137         hdcache->ErrorCallback = HAL_DCACHE_ErrorCallback;
1138         break;
1139 
1140       case HAL_DCACHE_MSPINIT_CB_ID :
1141         /* Legacy weak MspInit */
1142         hdcache->MspInitCallback = HAL_DCACHE_MspInit;
1143         break;
1144 
1145       case HAL_DCACHE_MSPDEINIT_CB_ID :
1146         /* Legacy weak MspDeInit */
1147         hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit;
1148         break;
1149 
1150       default :
1151         /* Update the error code */
1152         hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK;
1153 
1154         /* Return error status */
1155         status =  HAL_ERROR;
1156         break;
1157     }
1158   }
1159   else if (HAL_DCACHE_STATE_RESET == hdcache->State)
1160   {
1161     switch (CallbackID)
1162     {
1163       case HAL_DCACHE_MSPINIT_CB_ID :
1164         /* Legacy weak MspInit */
1165         hdcache->MspInitCallback = HAL_DCACHE_MspInit;
1166         break;
1167 
1168       case HAL_DCACHE_MSPDEINIT_CB_ID :
1169         /* Legacy weak MspDeInit */
1170         hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit;
1171         break;
1172 
1173       default :
1174         /* Update the error code */
1175         hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK;
1176 
1177         /* Return error status */
1178         status =  HAL_ERROR;
1179         break;
1180     }
1181   }
1182   else
1183   {
1184     /* Update the error code */
1185     hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK;
1186 
1187     /* Return error status */
1188     status =  HAL_ERROR;
1189   }
1190 
1191   return status;
1192 }
1193 
1194 /**
1195   * @brief  Start the Data Cache performance monitoring.
1196   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1197   *                 the configuration information for the specified DCACHEx peripheral.
1198   * @param  MonitorType Monitoring type
1199   *         This parameter can be a combination of the following values:
1200   *            @arg DCACHE_MONITOR_READ_HIT
1201   *            @arg DCACHE_MONITOR_READ_MISS
1202   *            @arg DCACHE_MONITOR_WRITE_HIT
1203   *            @arg DCACHE_MONITOR_WRITE_MISS
1204   *            @arg DCACHE_MONITOR_ALL
1205   * @retval HAL status
1206   */
HAL_DCACHE_Monitor_Start(DCACHE_HandleTypeDef * hdcache,uint32_t MonitorType)1207 HAL_StatusTypeDef HAL_DCACHE_Monitor_Start(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType)
1208 {
1209   /* Check the dcache handle allocation */
1210   if (hdcache == NULL)
1211   {
1212     return HAL_ERROR;
1213   }
1214 
1215   /* Check the parameters */
1216   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
1217   assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType));
1218 
1219   SET_BIT(hdcache->Instance->CR, MonitorType);
1220 
1221   return HAL_OK;
1222 }
1223 
1224 /**
1225   * @brief  Stop the Data Cache performance monitoring.
1226   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1227   *                 the configuration information for the specified DCACHEx peripheral.
1228   * @note   Stopping the monitoring does not reset the values.
1229   * @param  MonitorType Monitoring type
1230   *         This parameter can be a combination of the following values:
1231   *            @arg DCACHE_MONITOR_READ_HIT
1232   *            @arg DCACHE_MONITOR_READ_MISS
1233   *            @arg DCACHE_MONITOR_WRITE_HIT
1234   *            @arg DCACHE_MONITOR_WRITE_MISS
1235   *            @arg DCACHE_MONITOR_ALL
1236   * @retval HAL status
1237   */
HAL_DCACHE_Monitor_Stop(DCACHE_HandleTypeDef * hdcache,uint32_t MonitorType)1238 HAL_StatusTypeDef HAL_DCACHE_Monitor_Stop(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType)
1239 {
1240   /* Check the dcache handle allocation */
1241   if (hdcache == NULL)
1242   {
1243     return HAL_ERROR;
1244   }
1245 
1246   /* Check the parameters */
1247   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
1248   assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType));
1249 
1250   CLEAR_BIT(hdcache->Instance->CR, MonitorType);
1251 
1252   return HAL_OK;
1253 }
1254 
1255 /**
1256   * @brief  Reset the Data Cache performance monitoring values.
1257   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1258   *                 the configuration information for the specified DCACHEx peripheral.
1259   * @param  MonitorType Monitoring type
1260   *         This parameter can be a combination of the following values:
1261   *            @arg DCACHE_MONITOR_READ_HIT
1262   *            @arg DCACHE_MONITOR_READ_MISS
1263   *            @arg DCACHE_MONITOR_WRITE_HIT
1264   *            @arg DCACHE_MONITOR_WRITE_MISS
1265   *            @arg DCACHE_MONITOR_ALL
1266   * @retval HAL status
1267   */
HAL_DCACHE_Monitor_Reset(DCACHE_HandleTypeDef * hdcache,uint32_t MonitorType)1268 HAL_StatusTypeDef HAL_DCACHE_Monitor_Reset(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType)
1269 {
1270   /* Check the dcache handle allocation */
1271   if (hdcache == NULL)
1272   {
1273     return HAL_ERROR;
1274   }
1275 
1276   /* Check the parameters */
1277   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
1278   assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType));
1279 
1280   /* Force/Release reset */
1281   SET_BIT(hdcache->Instance->CR, (MonitorType << 2U));
1282   CLEAR_BIT(hdcache->Instance->CR, (MonitorType << 2U));
1283 
1284   return HAL_OK;
1285 }
1286 
1287 /**
1288   * @brief  Get the Data Cache performance Read Hit monitoring value.
1289   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1290   *                 the configuration information for the specified DCACHEx peripheral.
1291   * @note   Upon reaching the maximum value, monitor does not wrap.
1292   * @retval Read Hit monitoring value
1293   */
HAL_DCACHE_Monitor_GetReadHitValue(DCACHE_HandleTypeDef * hdcache)1294 uint32_t HAL_DCACHE_Monitor_GetReadHitValue(DCACHE_HandleTypeDef *hdcache)
1295 {
1296   /* Check the parameters */
1297   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
1298 
1299   /*return the Read Hit monitor value*/
1300   return hdcache->Instance->RHMONR;
1301 }
1302 
1303 /**
1304   * @brief  Get the Data Cache performance Read Miss monitoring value.
1305   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1306   *                 the configuration information for the specified DCACHEx peripheral.
1307   * @note   Upon reaching the maximum value, monitor does not wrap.
1308   * @retval Read Miss monitoring value
1309   */
HAL_DCACHE_Monitor_GetReadMissValue(DCACHE_HandleTypeDef * hdcache)1310 uint32_t HAL_DCACHE_Monitor_GetReadMissValue(DCACHE_HandleTypeDef *hdcache)
1311 {
1312   /* Check the parameters */
1313   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
1314 
1315   /*return the Read Miss monitor value*/
1316   return hdcache->Instance->RMMONR;
1317 }
1318 
1319 /**
1320   * @brief  Get the Data Cache performance Write Hit monitoring value.
1321   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1322   *                 the configuration information for the specified DCACHEx peripheral.
1323   * @note   Upon reaching the maximum value, monitor does not wrap.
1324   * @retval Write Hit monitoring value
1325   */
HAL_DCACHE_Monitor_GetWriteHitValue(DCACHE_HandleTypeDef * hdcache)1326 uint32_t HAL_DCACHE_Monitor_GetWriteHitValue(DCACHE_HandleTypeDef *hdcache)
1327 {
1328   /* Check the parameters */
1329   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
1330 
1331   /*return the Write Hit monitor value*/
1332   return hdcache->Instance->WHMONR;
1333 }
1334 
1335 /**
1336   * @brief  Get the Data Cache performance Write Miss monitoring value.
1337   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1338   *                 the configuration information for the specified DCACHEx peripheral.
1339   * @note   Upon reaching the maximum value, monitor does not wrap.
1340   * @retval Write Miss monitoring value
1341   */
HAL_DCACHE_Monitor_GetWriteMissValue(DCACHE_HandleTypeDef * hdcache)1342 uint32_t HAL_DCACHE_Monitor_GetWriteMissValue(DCACHE_HandleTypeDef *hdcache)
1343 {
1344   /* Check the parameters */
1345   assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance));
1346 
1347   /*return the Write Miss monitor value*/
1348   return hdcache->Instance->WMMONR;
1349 }
1350 /**
1351   * @}
1352   */
1353 
1354 /**
1355   * @brief  launch dcache command Clean, Invalidate or clean and invalidate by Addr.
1356   * @param  hdcache Pointer to a DCACHE_HandleTypeDef structure that contains
1357   *                 the configuration information for the specified DCACHEx peripheral.
1358   * @param  Command command to be applied for the dcache
1359   *                       DCACHE_COMMAND_INVALIDATE, DCACHE_COMMAND_CLEAN, DCACHE_COMMAND_CLEAN_INVALIDATE
1360   * @param  pAddr Start address of region to be Cleaned, Invalidated or Cleaned and Invalidated.
1361   * @param  dSize Size of the region to be Cleaned, Invalidated or Cleaned and Invalidated (in bytes).
1362   * @param  mode mode to be applied for the dcache
1363   *                       DCACHE_IT_MODE, DCACHE_POLLING_MODE.
1364   * @retval HAL status
1365   */
DCACHE_CommandByAddr(DCACHE_HandleTypeDef * hdcache,uint32_t Command,const uint32_t * const pAddr,uint32_t dSize,uint32_t mode)1366 static HAL_StatusTypeDef DCACHE_CommandByAddr(DCACHE_HandleTypeDef *hdcache, uint32_t Command,
1367                                               const uint32_t *const pAddr, uint32_t dSize, uint32_t mode)
1368 {
1369   HAL_StatusTypeDef status = HAL_OK;
1370   uint32_t op_addr = (uint32_t)pAddr;
1371   uint32_t tickstart;
1372 
1373   /* Check no ongoing operation */
1374   if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U)
1375   {
1376     /* Return busy status */
1377     status =  HAL_BUSY;
1378   }
1379   else
1380   {
1381     /* Update the error code */
1382     hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE;
1383 
1384     /* Update the DCACHE handle State */
1385     hdcache->State = HAL_DCACHE_STATE_READY;
1386 
1387     /* Make sure flags are reset */
1388     WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF));
1389 
1390     /* Fill area start address */
1391     WRITE_REG(hdcache->Instance->CMDRSADDRR, op_addr);
1392 
1393     /* Fill area end address */
1394     WRITE_REG(hdcache->Instance->CMDREADDRR, (op_addr + dSize - 1U));
1395 
1396     /* Set command */
1397     MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, Command);
1398 
1399     /* Enable IT if required */
1400     if (mode == DCACHE_IT_MODE)
1401     {
1402       /* Enable end of cache command interrupt */
1403       SET_BIT(hdcache->Instance->IER, DCACHE_IER_CMDENDIE);
1404 
1405       /* Launch cache command */
1406       SET_BIT(hdcache->Instance->CR, DCACHE_CR_STARTCMD);
1407     }
1408     else
1409     {
1410       /* Make sure that end of cache command interrupt is disabled */
1411       CLEAR_BIT(hdcache->Instance->IER, DCACHE_IER_CMDENDIE);
1412 
1413       /* Launch cache command */
1414       SET_BIT(hdcache->Instance->CR, DCACHE_CR_STARTCMD);
1415 
1416       /* Get timeout */
1417       tickstart = HAL_GetTick();
1418 
1419       /* Wait for end of cache command */
1420       while (READ_BIT(hdcache->Instance->SR, DCACHE_SR_CMDENDF) == 0U)
1421       {
1422         if ((HAL_GetTick() - tickstart) > DCACHE_COMMAND_TIMEOUT_VALUE)
1423         {
1424           if (READ_BIT(hdcache->Instance->SR, DCACHE_SR_CMDENDF) == 0U)
1425           {
1426             /* Update error code */
1427             hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT;
1428 
1429             /* Change the DCACHE state */
1430             hdcache->State = HAL_DCACHE_STATE_ERROR;
1431 
1432             /* Return error status */
1433             status =  HAL_ERROR;
1434             break;
1435           }
1436         }
1437       }
1438     }
1439   }
1440 
1441   return status;
1442 }
1443 
1444 
1445 #endif /* HAL_DCACHE_MODULE_ENABLED */
1446 
1447 
1448 /**
1449   * @}
1450   */
1451 
1452 /**
1453   * @}
1454   */
1455 
1456 /**
1457   * @}
1458   */
1459