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