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