1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_hal_icache.c
4   * @author  MCD Application Team
5   * @brief   ICACHE HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Instruction Cache (ICACHE).
8   *           + Initialization and Configuration
9   *           + Invalidate functions
10   *           + Monitoring management
11   *           + Memory address remap management
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2023 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                         ##### ICACHE main features #####
26   ==============================================================================
27   [..]
28     The Instruction Cache (ICACHE) is introduced on C-AHB code bus of
29     Cortex-M33 processor to improve performance when fetching instruction
30     and data from both internal and external memories. It allows close to
31     zero wait states performance.
32 
33     (+) The ICACHE provides two performance counters (Hit and Miss),
34         cache invalidate maintenance operation, error management and TrustZone
35         security support.
36 
37     (+) The ICACHE provides additionally the possibility to remap input address
38         falling into up to four memory regions (used to remap aliased code in
39         external memories to the internal Code region, for execution)
40 
41   ===============================================================================
42                         ##### How to use this driver #####
43   ===============================================================================
44   [..]
45      The ICACHE HAL driver can be used as follows:
46 
47     (#) Optionally configure the Instruction Cache mode with
48         HAL_ICACHE_ConfigAssociativityMode() if the default configuration
49         does not suit the application requirements.
50 
51     (#) Enable and disable the Instruction Cache with respectively
52         HAL_ICACHE_Enable() and HAL_ICACHE_Disable().
53         Use HAL_ICACHE_IsEnabled() to get the Instruction Cache status.
54         To ensure a deterministic cache behavior after power on, system reset or after
55         a call to @ref HAL_ICACHE_Disable(), the application must call
56         @ref HAL_ICACHE_WaitForInvalidateComplete(). Indeed on power on, system reset
57         or cache disable, an automatic cache invalidation procedure is launched and the
58         cache is bypassed until the operation completes.
59 
60     (#) Initiate the cache maintenance invalidation procedure with either
61         HAL_ICACHE_Invalidate() (blocking mode) or HAL_ICACHE_Invalidate_IT()
62         (interrupt mode). When interrupt mode is used, the callback function
63         HAL_ICACHE_InvalidateCompleteCallback() is called when the invalidate
64         procedure is complete. The function HAL_ICACHE_WaitForInvalidateComplete()
65         may be called to wait for the end of the invalidate procedure automatically
66         initiated when disabling the Instruction Cache with HAL_ICACHE_Disable().
67         The cache operation is bypassed during the invalidation procedure.
68 
69     (#) Use the performance monitoring counters for Hit and Miss with the following
70         functions: HAL_ICACHE_Monitor_Start(), HAL_ICACHE_Monitor_Stop(),
71         HAL_ICACHE_Monitor_Reset(), HAL_ICACHE_Monitor_GetHitValue() and
72         HAL_ICACHE_Monitor_GetMissValue()
73 
74     (#) Enable and disable up to four regions to remap input address from external
75         memories to the internal Code region for execution with
76         HAL_ICACHE_EnableRemapRegion() and HAL_ICACHE_DisableRemapRegion()
77 
78   @endverbatim
79   */
80 
81 /* Includes ------------------------------------------------------------------*/
82 #include "stm32h5xx_hal.h"
83 
84 /** @addtogroup STM32H5xx_HAL_Driver
85   * @{
86   */
87 
88 /** @defgroup ICACHE ICACHE
89   * @brief HAL ICACHE module driver
90   * @{
91   */
92 #if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED)
93 
94 /* Private typedef -----------------------------------------------------------*/
95 /* Private constants ---------------------------------------------------------*/
96 /** @addtogroup ICACHE_Private_Constants ICACHE Private Constants
97   * @{
98   */
99 #define ICACHE_INVALIDATE_TIMEOUT_VALUE        1U   /* 1ms */
100 #define ICACHE_DISABLE_TIMEOUT_VALUE           1U   /* 1ms */
101 
102 /**
103   * @}
104   */
105 
106 /* Private macros ------------------------------------------------------------*/
107 /** @defgroup ICACHE_Private_Macros ICACHE Private Macros
108   * @{
109   */
110 
111 #define IS_ICACHE_ASSOCIATIVITY_MODE(__MODE__) (((__MODE__) == ICACHE_1WAY) || \
112                                                 ((__MODE__) == ICACHE_2WAYS))
113 
114 #define IS_ICACHE_MONITOR_TYPE(__TYPE__)    (((__TYPE__) == ICACHE_MONITOR_HIT_MISS) || \
115                                              ((__TYPE__) == ICACHE_MONITOR_HIT)      || \
116                                              ((__TYPE__) == ICACHE_MONITOR_MISS))
117 
118 #if defined(ICACHE_CRRx_REN)
119 #define IS_ICACHE_REGION_NUMBER(__NUMBER__) ((__NUMBER__) < 4U)
120 
121 #define IS_ICACHE_REGION_SIZE(__SIZE__)     (((__SIZE__) == ICACHE_REGIONSIZE_2MB)   || \
122                                              ((__SIZE__) == ICACHE_REGIONSIZE_4MB)   || \
123                                              ((__SIZE__) == ICACHE_REGIONSIZE_8MB)   || \
124                                              ((__SIZE__) == ICACHE_REGIONSIZE_16MB)  || \
125                                              ((__SIZE__) == ICACHE_REGIONSIZE_32MB)  || \
126                                              ((__SIZE__) == ICACHE_REGIONSIZE_64MB)  || \
127                                              ((__SIZE__) == ICACHE_REGIONSIZE_128MB))
128 
129 #define IS_ICACHE_REGION_TRAFFIC_ROUTE(__TRAFFICROUTE__)  (((__TRAFFICROUTE__) == ICACHE_MASTER1_PORT) || \
130                                                            ((__TRAFFICROUTE__) == ICACHE_MASTER2_PORT))
131 
132 #define IS_ICACHE_REGION_OUTPUT_BURST_TYPE(__OUTPUTBURSTTYPE_) (((__OUTPUTBURSTTYPE_) == ICACHE_OUTPUT_BURST_WRAP) || \
133                                                                 ((__OUTPUTBURSTTYPE_) == ICACHE_OUTPUT_BURST_INCR))
134 
135 #endif /*  ICACHE_CRRx_REN */
136 /**
137   * @}
138   */
139 
140 /* Private variables ---------------------------------------------------------*/
141 /* Private function prototypes -----------------------------------------------*/
142 
143 /* Exported functions --------------------------------------------------------*/
144 
145 /** @defgroup ICACHE_Exported_Functions ICACHE Exported Functions
146   * @{
147   */
148 
149 /** @defgroup ICACHE_Exported_Functions_Group1 Initialization and control functions
150   * @brief    Initialization and control functions
151   *
152   @verbatim
153   ==============================================================================
154             ##### Initialization and control functions #####
155   ==============================================================================
156   [..]
157     This section provides functions allowing to initialize and control the
158     Instruction Cache (mode, invalidate procedure, performance counters).
159   @endverbatim
160   * @{
161   */
162 
163 /**
164   * @brief  Configure the Instruction Cache cache associativity mode selection.
165   * @param  AssociativityMode  Associativity mode selection
166   *         This parameter can be one of the following values:
167   *            @arg ICACHE_1WAY   1-way cache (direct mapped cache)
168   *            @arg ICACHE_2WAYS  2-ways set associative cache (default)
169   * @retval HAL status (HAL_OK/HAL_ERROR)
170   */
HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode)171 HAL_StatusTypeDef HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode)
172 {
173   HAL_StatusTypeDef status = HAL_OK;
174 
175   /* Check the parameters */
176   assert_param(IS_ICACHE_ASSOCIATIVITY_MODE(AssociativityMode));
177 
178   /* Check cache is not enabled */
179   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
180   {
181     status = HAL_ERROR;
182   }
183   else
184   {
185     MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, AssociativityMode);
186   }
187 
188   return status;
189 }
190 
191 /**
192   * @brief  DeInitialize the Instruction Cache.
193   * @retval HAL status (HAL_OK)
194   */
HAL_ICACHE_DeInit(void)195 HAL_StatusTypeDef HAL_ICACHE_DeInit(void)
196 {
197   /* Reset interrupt enable value */
198   WRITE_REG(ICACHE->IER, 0U);
199 
200   /* Clear any pending flags */
201   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF | ICACHE_FCR_CERRF);
202 
203   /* Disable cache then set default associative mode value */
204   CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN);
205   WRITE_REG(ICACHE->CR, ICACHE_CR_WAYSEL);
206 
207   /* Stop monitor and reset monitor values */
208   CLEAR_BIT(ICACHE->CR, ICACHE_MONITOR_HIT_MISS);
209   SET_BIT(ICACHE->CR, (ICACHE_MONITOR_HIT_MISS << 2U));
210   CLEAR_BIT(ICACHE->CR, (ICACHE_MONITOR_HIT_MISS << 2U));
211 
212 #if defined(ICACHE_CRRx_REN)
213   /* Reset regions configuration values */
214   WRITE_REG(ICACHE->CRR0, ICACHE_REGIONSIZE_2MB << ICACHE_CRRx_RSIZE_Pos);
215   WRITE_REG(ICACHE->CRR1, ICACHE_REGIONSIZE_2MB << ICACHE_CRRx_RSIZE_Pos);
216   WRITE_REG(ICACHE->CRR2, ICACHE_REGIONSIZE_2MB << ICACHE_CRRx_RSIZE_Pos);
217   WRITE_REG(ICACHE->CRR3, ICACHE_REGIONSIZE_2MB << ICACHE_CRRx_RSIZE_Pos);
218 #endif /*  ICACHE_CRRx_REN */
219 
220   return HAL_OK;
221 }
222 
223 /**
224   * @brief  Enable the Instruction Cache.
225   * @note   This function always returns HAL_OK even if there is any ongoing
226   *         cache operation. The Instruction Cache is bypassed until the
227   *         cache operation completes.
228   * @retval HAL status (HAL_OK)
229   */
HAL_ICACHE_Enable(void)230 HAL_StatusTypeDef HAL_ICACHE_Enable(void)
231 {
232   SET_BIT(ICACHE->CR, ICACHE_CR_EN);
233 
234   return HAL_OK;
235 }
236 
237 /**
238   * @brief  Disable the Instruction Cache.
239   * @note   This function waits for the cache being disabled but
240   *         not for the end of the automatic cache invalidation procedure.
241   * @retval HAL status (HAL_OK/HAL_TIMEOUT)
242   */
HAL_ICACHE_Disable(void)243 HAL_StatusTypeDef HAL_ICACHE_Disable(void)
244 {
245   HAL_StatusTypeDef status = HAL_OK;
246   uint32_t tickstart;
247 
248   /* Make sure BSYENDF is reset before to disable the instruction cache */
249   /* as it automatically starts a cache invalidation procedure */
250   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
251 
252   CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN);
253 
254   /* Get tick */
255   tickstart = HAL_GetTick();
256 
257   /* Wait for instruction cache being disabled */
258   while (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
259   {
260     if ((HAL_GetTick() - tickstart) > ICACHE_DISABLE_TIMEOUT_VALUE)
261     {
262       /* New check to avoid false timeout detection in case of preemption */
263       if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
264       {
265         status = HAL_TIMEOUT;
266         break;
267       }
268     }
269   }
270 
271   return status;
272 }
273 
274 /**
275   * @brief  Check whether the Instruction Cache is enabled or not.
276   * @retval Status (0: disabled, 1: enabled)
277   */
HAL_ICACHE_IsEnabled(void)278 uint32_t HAL_ICACHE_IsEnabled(void)
279 {
280   return ((READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) ? 1UL : 0UL);
281 }
282 
283 /**
284   * @brief  Invalidate the Instruction Cache.
285   * @note   This function waits for the end of cache invalidation procedure
286   *         and clears the associated BSYENDF flag.
287   * @retval HAL status (HAL_OK/HAL_ERROR/HAL_TIMEOUT)
288   */
HAL_ICACHE_Invalidate(void)289 HAL_StatusTypeDef HAL_ICACHE_Invalidate(void)
290 {
291   HAL_StatusTypeDef status;
292 
293   /* Check if no ongoing operation */
294   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) == 0U)
295   {
296     /* Launch cache invalidation */
297     SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV);
298   }
299 
300   status = HAL_ICACHE_WaitForInvalidateComplete();
301 
302   return status;
303 }
304 
305 /**
306   * @brief  Invalidate the Instruction Cache with interrupt.
307   * @note   This function launches cache invalidation and returns.
308   *         User application shall resort to interrupt generation to check
309   *         the end of the cache invalidation with the BSYENDF flag and the
310   *         HAL_ICACHE_InvalidateCompleteCallback() callback.
311   * @retval HAL status (HAL_OK/HAL_ERROR)
312   */
HAL_ICACHE_Invalidate_IT(void)313 HAL_StatusTypeDef HAL_ICACHE_Invalidate_IT(void)
314 {
315   HAL_StatusTypeDef status = HAL_OK;
316 
317   /* Check no ongoing operation */
318   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
319   {
320     status = HAL_ERROR;
321   }
322   else
323   {
324     /* Make sure BSYENDF is reset before to start cache invalidation */
325     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
326 
327     /* Enable end of cache invalidation interrupt */
328     SET_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE);
329 
330     /* Launch cache invalidation */
331     SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV);
332   }
333 
334   return status;
335 }
336 
337 /**
338   * @brief Wait for the end of the Instruction Cache invalidate procedure.
339   * @note This function checks and clears the BSYENDF flag when set.
340   * @retval HAL status (HAL_OK/HAL_TIMEOUT)
341   */
HAL_ICACHE_WaitForInvalidateComplete(void)342 HAL_StatusTypeDef HAL_ICACHE_WaitForInvalidateComplete(void)
343 {
344   HAL_StatusTypeDef status = HAL_OK;
345   uint32_t tickstart;
346 
347   /* Check if ongoing invalidation operation */
348   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
349   {
350     /* Get tick */
351     tickstart = HAL_GetTick();
352 
353     /* Wait for end of cache invalidation */
354     while (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U)
355     {
356       if ((HAL_GetTick() - tickstart) > ICACHE_INVALIDATE_TIMEOUT_VALUE)
357       {
358         /* New check to avoid false timeout detection in case of preemption */
359         if (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U)
360         {
361           status = HAL_TIMEOUT;
362           break;
363         }
364       }
365     }
366   }
367 
368   /* Clear BSYENDF */
369   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
370 
371   return status;
372 }
373 
374 
375 /**
376   * @brief  Start the Instruction Cache performance monitoring.
377   * @param  MonitorType  Monitoring type
378   *         This parameter can be one of the following values:
379   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
380   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
381   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
382   * @retval HAL status (HAL_OK)
383   */
HAL_ICACHE_Monitor_Start(uint32_t MonitorType)384 HAL_StatusTypeDef HAL_ICACHE_Monitor_Start(uint32_t MonitorType)
385 {
386   /* Check the parameters */
387   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
388 
389   SET_BIT(ICACHE->CR, MonitorType);
390 
391   return HAL_OK;
392 }
393 
394 /**
395   * @brief  Stop the Instruction Cache performance monitoring.
396   * @note   Stopping the monitoring does not reset the values.
397   * @param  MonitorType  Monitoring type
398   *         This parameter can be one of the following values:
399   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
400   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
401   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
402   * @retval HAL status (HAL_OK)
403   */
HAL_ICACHE_Monitor_Stop(uint32_t MonitorType)404 HAL_StatusTypeDef HAL_ICACHE_Monitor_Stop(uint32_t MonitorType)
405 {
406   /* Check the parameters */
407   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
408 
409   CLEAR_BIT(ICACHE->CR, MonitorType);
410 
411   return HAL_OK;
412 }
413 
414 /**
415   * @brief  Reset the Instruction Cache performance monitoring values.
416   * @param  MonitorType  Monitoring type
417   *         This parameter can be one of the following values:
418   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
419   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
420   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
421   * @retval HAL status (HAL_OK)
422   */
HAL_ICACHE_Monitor_Reset(uint32_t MonitorType)423 HAL_StatusTypeDef HAL_ICACHE_Monitor_Reset(uint32_t MonitorType)
424 {
425   /* Check the parameters */
426   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
427 
428   /* Force/Release reset */
429   SET_BIT(ICACHE->CR, (MonitorType << 2U));
430   CLEAR_BIT(ICACHE->CR, (MonitorType << 2U));
431 
432   return HAL_OK;
433 }
434 
435 /**
436   * @brief  Get the Instruction Cache performance Hit monitoring value.
437   * @note   Upon reaching the 32-bit maximum value, monitor does not wrap.
438   * @retval Hit monitoring value
439   */
HAL_ICACHE_Monitor_GetHitValue(void)440 uint32_t HAL_ICACHE_Monitor_GetHitValue(void)
441 {
442   return (ICACHE->HMONR);
443 }
444 
445 /**
446   * @brief  Get the Instruction Cache performance Miss monitoring value.
447   * @note   Upon reaching the 32-bit maximum value, monitor does not wrap.
448   * @retval Miss monitoring value
449   */
HAL_ICACHE_Monitor_GetMissValue(void)450 uint32_t HAL_ICACHE_Monitor_GetMissValue(void)
451 {
452   return (ICACHE->MMONR);
453 }
454 
455 /**
456   * @}
457   */
458 
459 /** @defgroup ICACHE_Exported_Functions_Group2 IRQ and callback functions
460   * @brief    IRQ and callback functions
461   *
462   @verbatim
463   ==============================================================================
464             ##### IRQ and callback functions #####
465   ==============================================================================
466   [..]
467     This section provides functions allowing to handle ICACHE global interrupt
468     and the associated callback functions.
469   @endverbatim
470   * @{
471   */
472 
473 /**
474   * @brief Handle the Instruction Cache interrupt request.
475   * @note This function should be called under the ICACHE_IRQHandler().
476   * @note This function respectively disables the interrupt and clears the
477   *       flag of any pending flag before calling the associated user callback.
478   * @retval None
479   */
HAL_ICACHE_IRQHandler(void)480 void HAL_ICACHE_IRQHandler(void)
481 {
482   /* Get current interrupt flags and interrupt sources value */
483   uint32_t itflags   = READ_REG(ICACHE->SR);
484   uint32_t itsources = READ_REG(ICACHE->IER);
485 
486   /* Check Instruction cache Error interrupt flag */
487   if (((itflags & itsources) & ICACHE_FLAG_ERROR) != 0U)
488   {
489     /* Disable error interrupt */
490     CLEAR_BIT(ICACHE->IER, ICACHE_IER_ERRIE);
491 
492     /* Clear ERR pending flag */
493     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CERRF);
494 
495     /* Instruction cache error interrupt user callback */
496     HAL_ICACHE_ErrorCallback();
497   }
498 
499   /* Check Instruction cache BusyEnd interrupt flag */
500   if (((itflags & itsources) & ICACHE_FLAG_BUSYEND) != 0U)
501   {
502     /* Disable end of cache invalidation interrupt */
503     CLEAR_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE);
504 
505     /* Clear BSYENDF pending flag */
506     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
507 
508     /* Instruction cache busyend interrupt user callback */
509     HAL_ICACHE_InvalidateCompleteCallback();
510   }
511 }
512 
513 /**
514   * @brief  Cache invalidation complete callback.
515   */
HAL_ICACHE_InvalidateCompleteCallback(void)516 __weak void HAL_ICACHE_InvalidateCompleteCallback(void)
517 {
518   /* NOTE : This function should not be modified, when the callback is needed,
519             the HAL_ICACHE_InvalidateCompleteCallback() should be implemented in the user file
520    */
521 }
522 
523 /**
524   * @brief  Error callback.
525   */
HAL_ICACHE_ErrorCallback(void)526 __weak void HAL_ICACHE_ErrorCallback(void)
527 {
528   /* NOTE : This function should not be modified, when the callback is needed,
529             the HAL_ICACHE_ErrorCallback() should be implemented in the user file
530    */
531 }
532 
533 /**
534   * @}
535   */
536 
537 #if defined(ICACHE_CRRx_REN)
538 /** @defgroup ICACHE_Exported_Functions_Group3 Memory remapped regions functions
539   * @brief    Memory remapped regions functions
540   *
541   @verbatim
542   ==============================================================================
543             ##### Memory remapped regions functions #####
544   ==============================================================================
545   [..]
546     This section provides functions allowing to manage the remapping of
547     external memories to internal Code for execution.
548   @endverbatim
549   * @{
550   */
551 
552 /**
553   * @brief  Configure and enable a region for memory remapping.
554   * @note   The Instruction Cache and the region must be disabled.
555   * @param  Region   Region number
556                      This parameter can be a value of @arg @ref ICACHE_Region
557   * @param  pRegionConfig  Pointer to structure of ICACHE region configuration parameters
558   * @retval HAL status (HAL_OK/HAL_ERROR)
559   */
HAL_ICACHE_EnableRemapRegion(uint32_t Region,const ICACHE_RegionConfigTypeDef * const pRegionConfig)560 HAL_StatusTypeDef  HAL_ICACHE_EnableRemapRegion(uint32_t Region, const ICACHE_RegionConfigTypeDef *const pRegionConfig)
561 {
562   HAL_StatusTypeDef status = HAL_OK;
563   __IO uint32_t *p_reg;
564   uint32_t value;
565 
566   /* Check the parameters */
567   assert_param(IS_ICACHE_REGION_NUMBER(Region));
568   assert_param(IS_ICACHE_REGION_SIZE(pRegionConfig->Size));
569   assert_param(IS_ICACHE_REGION_TRAFFIC_ROUTE(pRegionConfig->TrafficRoute));
570   assert_param(IS_ICACHE_REGION_OUTPUT_BURST_TYPE(pRegionConfig->OutputBurstType));
571 
572   /* Check cache is not enabled */
573   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
574   {
575     status = HAL_ERROR;
576   }
577   else
578   {
579     /* Get region control register address */
580     p_reg = &(ICACHE->CRR0) + (1U * Region);
581 
582     /* Check region is not already enabled */
583     if ((*p_reg & ICACHE_CRRx_REN) != 0U)
584     {
585       status = HAL_ERROR;
586     }
587     else
588     {
589       /* Region 2MB:   BaseAddress size 8 bits, RemapAddress size 11 bits */
590       /* Region 4MB:   BaseAddress size 7 bits, RemapAddress size 10 bits */
591       /* Region 8MB:   BaseAddress size 6 bits, RemapAddress size 9 bits  */
592       /* Region 16MB:  BaseAddress size 5 bits, RemapAddress size 8 bits  */
593       /* Region 32MB:  BaseAddress size 4 bits, RemapAddress size 7 bits  */
594       /* Region 64MB:  BaseAddress size 3 bits, RemapAddress size 6 bits  */
595       /* Region 128MB: BaseAddress size 2 bits, RemapAddress size 5 bits  */
596       value  = ((pRegionConfig->BaseAddress & 0x1FFFFFFFU) >> 21U) & \
597                (0xFFU & ~(pRegionConfig->Size - 1U));
598       value |= ((pRegionConfig->RemapAddress >> 5U) & \
599                 ((uint32_t)(0x7FFU & ~(pRegionConfig->Size - 1U)) << ICACHE_CRRx_REMAPADDR_Pos));
600       value |= (pRegionConfig->Size << ICACHE_CRRx_RSIZE_Pos) | pRegionConfig->TrafficRoute | \
601                pRegionConfig->OutputBurstType;
602       *p_reg = (value | ICACHE_CRRx_REN);
603     }
604   }
605 
606   return status;
607 }
608 
609 /**
610   * @brief  Disable the memory remapping for a predefined region.
611   * @param  Region   Region number
612                      This parameter can be a value of @arg @ref ICACHE_Region
613   * @retval HAL status (HAL_OK/HAL_ERROR)
614   */
HAL_ICACHE_DisableRemapRegion(uint32_t Region)615 HAL_StatusTypeDef  HAL_ICACHE_DisableRemapRegion(uint32_t Region)
616 {
617   HAL_StatusTypeDef status = HAL_OK;
618   __IO uint32_t *p_reg;
619 
620   /* Check the parameters */
621   assert_param(IS_ICACHE_REGION_NUMBER(Region));
622 
623   /* Check cache is not enabled */
624   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
625   {
626     status = HAL_ERROR;
627   }
628   else
629   {
630     /* Get region control register address */
631     p_reg = &(ICACHE->CRR0) + (1U * Region);
632 
633     *p_reg &= ~ICACHE_CRRx_REN;
634   }
635 
636   return status;
637 }
638 
639 
640 /**
641   * @}
642   */
643 #endif /*  ICACHE_CRRx_REN */
644 
645 /**
646   * @}
647   */
648 
649 #endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED */
650 
651 /**
652   * @}
653   */
654 
655 /**
656   * @}
657   */
658