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