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