1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_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) 2022 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 "stm32wbaxx_hal.h"
83 
84 /** @addtogroup STM32WBAxx_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 #define IS_ICACHE_REGION_NUMBER(__NUMBER__) ((__NUMBER__) < 4U)
119 
120 #define IS_ICACHE_REGION_SIZE(__SIZE__)     (((__SIZE__) == ICACHE_REGIONSIZE_2MB)   || \
121                                              ((__SIZE__) == ICACHE_REGIONSIZE_4MB)   || \
122                                              ((__SIZE__) == ICACHE_REGIONSIZE_8MB)   || \
123                                              ((__SIZE__) == ICACHE_REGIONSIZE_16MB)  || \
124                                              ((__SIZE__) == ICACHE_REGIONSIZE_32MB)  || \
125                                              ((__SIZE__) == ICACHE_REGIONSIZE_64MB)  || \
126                                              ((__SIZE__) == ICACHE_REGIONSIZE_128MB))
127 
128 #define IS_ICACHE_REGION_TRAFFIC_ROUTE(__TRAFFICROUTE__)  (((__TRAFFICROUTE__) == ICACHE_MASTER1_PORT) || \
129                                                            ((__TRAFFICROUTE__) == ICACHE_MASTER2_PORT))
130 
131 #define IS_ICACHE_REGION_OUTPUT_BURST_TYPE(__OUTPUTBURSTTYPE_) (((__OUTPUTBURSTTYPE_) == ICACHE_OUTPUT_BURST_WRAP) || \
132                                                                 ((__OUTPUTBURSTTYPE_) == ICACHE_OUTPUT_BURST_INCR))
133 
134 /**
135   * @}
136   */
137 
138 /* Private variables ---------------------------------------------------------*/
139 /* Private function prototypes -----------------------------------------------*/
140 
141 /* Exported functions --------------------------------------------------------*/
142 
143 /** @defgroup ICACHE_Exported_Functions ICACHE Exported Functions
144   * @{
145   */
146 
147 /** @defgroup ICACHE_Exported_Functions_Group1 Initialization and control functions
148   * @brief    Initialization and control functions
149   *
150   @verbatim
151   ==============================================================================
152             ##### Initialization and control functions #####
153   ==============================================================================
154   [..]
155     This section provides functions allowing to initialize and control the
156     Instruction Cache (mode, invalidate procedure, performance counters).
157   @endverbatim
158   * @{
159   */
160 
161 /**
162   * @brief  Configure the Instruction Cache cache associativity mode selection.
163   * @param  AssociativityMode  Associativity mode selection
164   *         This parameter can be one of the following values:
165   *            @arg ICACHE_1WAY   1-way cache (direct mapped cache)
166   *            @arg ICACHE_2WAYS  2-ways set associative cache (default)
167   * @retval HAL status (HAL_OK/HAL_ERROR)
168   */
HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode)169 HAL_StatusTypeDef HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode)
170 {
171   HAL_StatusTypeDef status = HAL_OK;
172 
173   /* Check the parameters */
174   assert_param(IS_ICACHE_ASSOCIATIVITY_MODE(AssociativityMode));
175 
176   /* Check cache is not enabled */
177   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
178   {
179     status = HAL_ERROR;
180   }
181   else
182   {
183     MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, AssociativityMode);
184   }
185 
186   return status;
187 }
188 
189 /**
190   * @brief  DeInitialize the Instruction Cache.
191   * @retval HAL status (HAL_OK)
192   */
HAL_ICACHE_DeInit(void)193 HAL_StatusTypeDef HAL_ICACHE_DeInit(void)
194 {
195   /* Reset interrupt enable value */
196   WRITE_REG(ICACHE->IER, 0U);
197 
198   /* Clear any pending flags */
199   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF | ICACHE_FCR_CERRF);
200 
201   /* Disable cache then set default associative mode value */
202   CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN);
203   WRITE_REG(ICACHE->CR, ICACHE_CR_WAYSEL);
204 
205   /* Stop monitor and reset monitor values */
206   CLEAR_BIT(ICACHE->CR, ICACHE_MONITOR_HIT_MISS);
207   SET_BIT(ICACHE->CR, (ICACHE_MONITOR_HIT_MISS << 2U));
208   CLEAR_BIT(ICACHE->CR, (ICACHE_MONITOR_HIT_MISS << 2U));
209 
210   /* Reset regions configuration values */
211   WRITE_REG(ICACHE->CRR0, ICACHE_REGIONSIZE_2MB << ICACHE_CRRx_RSIZE_Pos);
212   WRITE_REG(ICACHE->CRR1, ICACHE_REGIONSIZE_2MB << ICACHE_CRRx_RSIZE_Pos);
213   WRITE_REG(ICACHE->CRR2, ICACHE_REGIONSIZE_2MB << ICACHE_CRRx_RSIZE_Pos);
214   WRITE_REG(ICACHE->CRR3, ICACHE_REGIONSIZE_2MB << ICACHE_CRRx_RSIZE_Pos);
215 
216   return HAL_OK;
217 }
218 
219 /**
220   * @brief  Enable the Instruction Cache.
221   * @note   This function always returns HAL_OK even if there is any ongoing
222   *         cache operation. The Instruction Cache is bypassed until the
223   *         cache operation completes.
224   * @retval HAL status (HAL_OK)
225   */
HAL_ICACHE_Enable(void)226 HAL_StatusTypeDef HAL_ICACHE_Enable(void)
227 {
228   SET_BIT(ICACHE->CR, ICACHE_CR_EN);
229 
230   return HAL_OK;
231 }
232 
233 /**
234   * @brief  Disable the Instruction Cache.
235   * @note   This function waits for the cache being disabled but
236   *         not for the end of the automatic cache invalidation procedure.
237   * @retval HAL status (HAL_OK/HAL_TIMEOUT)
238   */
HAL_ICACHE_Disable(void)239 HAL_StatusTypeDef HAL_ICACHE_Disable(void)
240 {
241   HAL_StatusTypeDef status = HAL_OK;
242   uint32_t tickstart;
243 
244   /* Make sure BSYENDF is reset before to disable the instruction cache */
245   /* as it automatically starts a cache invalidation procedure */
246   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
247 
248   CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN);
249 
250   /* Get tick */
251   tickstart = HAL_GetTick();
252 
253   /* Wait for instruction cache being disabled */
254   while (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
255   {
256     if ((HAL_GetTick() - tickstart) > ICACHE_DISABLE_TIMEOUT_VALUE)
257     {
258       /* New check to avoid false timeout detection in case of preemption */
259       if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
260       {
261         status = HAL_TIMEOUT;
262         break;
263       }
264     }
265   }
266 
267   return status;
268 }
269 
270 /**
271   * @brief  Check whether the Instruction Cache is enabled or not.
272   * @retval Status (0: disabled, 1: enabled)
273   */
HAL_ICACHE_IsEnabled(void)274 uint32_t HAL_ICACHE_IsEnabled(void)
275 {
276   return ((READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) ? 1UL : 0UL);
277 }
278 
279 /**
280   * @brief  Invalidate the Instruction Cache.
281   * @note   This function waits for the end of cache invalidation procedure
282   *         and clears the associated BSYENDF flag.
283   * @retval HAL status (HAL_OK/HAL_ERROR/HAL_TIMEOUT)
284   */
HAL_ICACHE_Invalidate(void)285 HAL_StatusTypeDef HAL_ICACHE_Invalidate(void)
286 {
287   HAL_StatusTypeDef status;
288 
289   /* Check if no ongoing operation */
290   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) == 0U)
291   {
292     /* Launch cache invalidation */
293     SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV);
294   }
295 
296   status = HAL_ICACHE_WaitForInvalidateComplete();
297 
298   return status;
299 }
300 
301 /**
302   * @brief  Invalidate the Instruction Cache with interrupt.
303   * @note   This function launches cache invalidation and returns.
304   *         User application shall resort to interrupt generation to check
305   *         the end of the cache invalidation with the BSYENDF flag and the
306   *         HAL_ICACHE_InvalidateCompleteCallback() callback.
307   * @retval HAL status (HAL_OK/HAL_ERROR)
308   */
HAL_ICACHE_Invalidate_IT(void)309 HAL_StatusTypeDef HAL_ICACHE_Invalidate_IT(void)
310 {
311   HAL_StatusTypeDef status = HAL_OK;
312 
313   /* Check no ongoing operation */
314   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
315   {
316     status = HAL_ERROR;
317   }
318   else
319   {
320     /* Make sure BSYENDF is reset before to start cache invalidation */
321     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
322 
323     /* Enable end of cache invalidation interrupt */
324     SET_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE);
325 
326     /* Launch cache invalidation */
327     SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV);
328   }
329 
330   return status;
331 }
332 
333 /**
334   * @brief Wait for the end of the Instruction Cache invalidate procedure.
335   * @note This function checks and clears the BSYENDF flag when set.
336   * @retval HAL status (HAL_OK/HAL_TIMEOUT)
337   */
HAL_ICACHE_WaitForInvalidateComplete(void)338 HAL_StatusTypeDef HAL_ICACHE_WaitForInvalidateComplete(void)
339 {
340   HAL_StatusTypeDef status = HAL_OK;
341   uint32_t tickstart;
342 
343   /* Check if ongoing invalidation operation */
344   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
345   {
346     /* Get tick */
347     tickstart = HAL_GetTick();
348 
349     /* Wait for end of cache invalidation */
350     while (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U)
351     {
352       if ((HAL_GetTick() - tickstart) > ICACHE_INVALIDATE_TIMEOUT_VALUE)
353       {
354         /* New check to avoid false timeout detection in case of preemption */
355         if (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U)
356         {
357           status = HAL_TIMEOUT;
358           break;
359         }
360       }
361     }
362   }
363 
364   /* Clear BSYENDF */
365   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
366 
367   return status;
368 }
369 
370 
371 /**
372   * @brief  Start the Instruction Cache performance monitoring.
373   * @param  MonitorType  Monitoring type
374   *         This parameter can be one of the following values:
375   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
376   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
377   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
378   * @retval HAL status (HAL_OK)
379   */
HAL_ICACHE_Monitor_Start(uint32_t MonitorType)380 HAL_StatusTypeDef HAL_ICACHE_Monitor_Start(uint32_t MonitorType)
381 {
382   /* Check the parameters */
383   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
384 
385   SET_BIT(ICACHE->CR, MonitorType);
386 
387   return HAL_OK;
388 }
389 
390 /**
391   * @brief  Stop the Instruction Cache performance monitoring.
392   * @note   Stopping the monitoring does not reset the values.
393   * @param  MonitorType  Monitoring type
394   *         This parameter can be one of the following values:
395   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
396   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
397   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
398   * @retval HAL status (HAL_OK)
399   */
HAL_ICACHE_Monitor_Stop(uint32_t MonitorType)400 HAL_StatusTypeDef HAL_ICACHE_Monitor_Stop(uint32_t MonitorType)
401 {
402   /* Check the parameters */
403   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
404 
405   CLEAR_BIT(ICACHE->CR, MonitorType);
406 
407   return HAL_OK;
408 }
409 
410 /**
411   * @brief  Reset the Instruction Cache performance monitoring values.
412   * @param  MonitorType  Monitoring type
413   *         This parameter can be one of the following values:
414   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
415   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
416   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
417   * @retval HAL status (HAL_OK)
418   */
HAL_ICACHE_Monitor_Reset(uint32_t MonitorType)419 HAL_StatusTypeDef HAL_ICACHE_Monitor_Reset(uint32_t MonitorType)
420 {
421   /* Check the parameters */
422   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
423 
424   /* Force/Release reset */
425   SET_BIT(ICACHE->CR, (MonitorType << 2U));
426   CLEAR_BIT(ICACHE->CR, (MonitorType << 2U));
427 
428   return HAL_OK;
429 }
430 
431 /**
432   * @brief  Get the Instruction Cache performance Hit monitoring value.
433   * @note   Upon reaching the 32-bit maximum value, monitor does not wrap.
434   * @retval Hit monitoring value
435   */
HAL_ICACHE_Monitor_GetHitValue(void)436 uint32_t HAL_ICACHE_Monitor_GetHitValue(void)
437 {
438   return (ICACHE->HMONR);
439 }
440 
441 /**
442   * @brief  Get the Instruction Cache performance Miss monitoring value.
443   * @note   Upon reaching the 32-bit maximum value, monitor does not wrap.
444   * @retval Miss monitoring value
445   */
HAL_ICACHE_Monitor_GetMissValue(void)446 uint32_t HAL_ICACHE_Monitor_GetMissValue(void)
447 {
448   return (ICACHE->MMONR);
449 }
450 
451 /**
452   * @}
453   */
454 
455 /** @defgroup ICACHE_Exported_Functions_Group2 IRQ and callback functions
456   * @brief    IRQ and callback functions
457   *
458   @verbatim
459   ==============================================================================
460             ##### IRQ and callback functions #####
461   ==============================================================================
462   [..]
463     This section provides functions allowing to handle ICACHE global interrupt
464     and the associated callback functions.
465   @endverbatim
466   * @{
467   */
468 
469 /**
470   * @brief Handle the Instruction Cache interrupt request.
471   * @note This function should be called under the ICACHE_IRQHandler().
472   * @note This function respectively disables the interrupt and clears the
473   *       flag of any pending flag before calling the associated user callback.
474   * @retval None
475   */
HAL_ICACHE_IRQHandler(void)476 void HAL_ICACHE_IRQHandler(void)
477 {
478   /* Get current interrupt flags and interrupt sources value */
479   uint32_t itflags   = READ_REG(ICACHE->SR);
480   uint32_t itsources = READ_REG(ICACHE->IER);
481 
482   /* Check Instruction cache Error interrupt flag */
483   if (((itflags & itsources) & ICACHE_FLAG_ERROR) != 0U)
484   {
485     /* Disable error interrupt */
486     CLEAR_BIT(ICACHE->IER, ICACHE_IER_ERRIE);
487 
488     /* Clear ERR pending flag */
489     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CERRF);
490 
491     /* Instruction cache error interrupt user callback */
492     HAL_ICACHE_ErrorCallback();
493   }
494 
495   /* Check Instruction cache BusyEnd interrupt flag */
496   if (((itflags & itsources) & ICACHE_FLAG_BUSYEND) != 0U)
497   {
498     /* Disable end of cache invalidation interrupt */
499     CLEAR_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE);
500 
501     /* Clear BSYENDF pending flag */
502     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
503 
504     /* Instruction cache busyend interrupt user callback */
505     HAL_ICACHE_InvalidateCompleteCallback();
506   }
507 }
508 
509 /**
510   * @brief  Cache invalidation complete callback.
511   */
HAL_ICACHE_InvalidateCompleteCallback(void)512 __weak void HAL_ICACHE_InvalidateCompleteCallback(void)
513 {
514   /* NOTE : This function should not be modified, when the callback is needed,
515             the HAL_ICACHE_InvalidateCompleteCallback() should be implemented in the user file
516    */
517 }
518 
519 /**
520   * @brief  Error callback.
521   */
HAL_ICACHE_ErrorCallback(void)522 __weak void HAL_ICACHE_ErrorCallback(void)
523 {
524   /* NOTE : This function should not be modified, when the callback is needed,
525             the HAL_ICACHE_ErrorCallback() should be implemented in the user file
526    */
527 }
528 
529 /**
530   * @}
531   */
532 
533 /** @defgroup ICACHE_Exported_Functions_Group3 Memory remapped regions functions
534   * @brief    Memory remapped regions functions
535   *
536   @verbatim
537   ==============================================================================
538             ##### Memory remapped regions functions #####
539   ==============================================================================
540   [..]
541     This section provides functions allowing to manage the remapping of
542     external memories to internal Code for execution.
543   @endverbatim
544   * @{
545   */
546 
547 /**
548   * @brief  Configure and enable a region for memory remapping.
549   * @note   The Instruction Cache and the region must be disabled.
550   * @param  Region   Region number
551                      This parameter can be a value of @arg @ref ICACHE_Region
552   * @param  pRegionConfig  Pointer to structure of ICACHE region configuration parameters
553   * @retval HAL status (HAL_OK/HAL_ERROR)
554   */
HAL_ICACHE_EnableRemapRegion(uint32_t Region,const ICACHE_RegionConfigTypeDef * const pRegionConfig)555 HAL_StatusTypeDef  HAL_ICACHE_EnableRemapRegion(uint32_t Region, const ICACHE_RegionConfigTypeDef *const pRegionConfig)
556 {
557   HAL_StatusTypeDef status = HAL_OK;
558   __IO uint32_t *p_reg;
559   uint32_t value;
560 
561   /* Check the parameters */
562   assert_param(IS_ICACHE_REGION_NUMBER(Region));
563   assert_param(IS_ICACHE_REGION_SIZE(pRegionConfig->Size));
564   assert_param(IS_ICACHE_REGION_TRAFFIC_ROUTE(pRegionConfig->TrafficRoute));
565   assert_param(IS_ICACHE_REGION_OUTPUT_BURST_TYPE(pRegionConfig->OutputBurstType));
566 
567   /* Check cache is not enabled */
568   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
569   {
570     status = HAL_ERROR;
571   }
572   else
573   {
574     /* Get region control register address */
575     p_reg = &(ICACHE->CRR0) + (1U * Region);
576 
577     /* Check region is not already enabled */
578     if ((*p_reg & ICACHE_CRRx_REN) != 0U)
579     {
580       status = HAL_ERROR;
581     }
582     else
583     {
584       /* Region 2MB:   BaseAddress size 8 bits, RemapAddress size 11 bits */
585       /* Region 4MB:   BaseAddress size 7 bits, RemapAddress size 10 bits */
586       /* Region 8MB:   BaseAddress size 6 bits, RemapAddress size 9 bits  */
587       /* Region 16MB:  BaseAddress size 5 bits, RemapAddress size 8 bits  */
588       /* Region 32MB:  BaseAddress size 4 bits, RemapAddress size 7 bits  */
589       /* Region 64MB:  BaseAddress size 3 bits, RemapAddress size 6 bits  */
590       /* Region 128MB: BaseAddress size 2 bits, RemapAddress size 5 bits  */
591       value  = ((pRegionConfig->BaseAddress & 0x1FFFFFFFU) >> 21U) & \
592                (0xFFU & ~(pRegionConfig->Size - 1U));
593       value |= ((pRegionConfig->RemapAddress >> 5U) & \
594                 ((uint32_t)(0x7FFU & ~(pRegionConfig->Size - 1U)) << ICACHE_CRRx_REMAPADDR_Pos));
595       value |= (pRegionConfig->Size << ICACHE_CRRx_RSIZE_Pos) | pRegionConfig->TrafficRoute | \
596                pRegionConfig->OutputBurstType;
597       *p_reg = (value | ICACHE_CRRx_REN);
598     }
599   }
600 
601   return status;
602 }
603 
604 /**
605   * @brief  Disable the memory remapping for a predefined region.
606   * @param  Region   Region number
607                      This parameter can be a value of @arg @ref ICACHE_Region
608   * @retval HAL status (HAL_OK/HAL_ERROR)
609   */
HAL_ICACHE_DisableRemapRegion(uint32_t Region)610 HAL_StatusTypeDef  HAL_ICACHE_DisableRemapRegion(uint32_t Region)
611 {
612   HAL_StatusTypeDef status = HAL_OK;
613   __IO uint32_t *p_reg;
614 
615   /* Check the parameters */
616   assert_param(IS_ICACHE_REGION_NUMBER(Region));
617 
618   /* Check cache is not enabled */
619   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
620   {
621     status = HAL_ERROR;
622   }
623   else
624   {
625     /* Get region control register address */
626     p_reg = &(ICACHE->CRR0) + (1U * Region);
627 
628     *p_reg &= ~ICACHE_CRRx_REN;
629   }
630 
631   return status;
632 }
633 
634 
635 /**
636   * @}
637   */
638 
639 /**
640   * @}
641   */
642 
643 #endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED */
644 
645 /**
646   * @}
647   */
648 
649 /**
650   * @}
651   */
652