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