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