1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_hal_cortex.c
4   * @author  MCD Application Team
5   * @brief   CORTEX HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the CORTEX:
8   *           + Initialization and Configuration functions
9   *           + Peripheral Control functions
10   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2019 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file in
18   * 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     [..]
28     *** How to configure Interrupts using CORTEX HAL driver ***
29     ===========================================================
30     [..]
31     This section provides functions allowing to configure the NVIC interrupts (IRQ).
32     The Cortex-M33 exceptions are managed by CMSIS functions.
33 
34     (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping() function.
35     (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
36     (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
37 
38      -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ pre-emption is no more possible.
39          The pending IRQ priority will be managed only by the sub priority.
40 
41      -@- IRQ priority order (sorted by highest to lowest priority):
42         (+@) Lowest pre-emption priority
43         (+@) Lowest sub priority
44         (+@) Lowest hardware priority (IRQ number)
45 
46     [..]
47     *** How to configure SysTick using CORTEX HAL driver ***
48     ========================================================
49     [..]
50     Setup SysTick Timer for time base.
51 
52    (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which
53        is a CMSIS function that:
54         (++) Configures the SysTick Reload register with value passed as function parameter.
55         (++) Configures the SysTick IRQ priority to the lowest value (0x07).
56         (++) Resets the SysTick Counter register.
57         (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
58         (++) Enables the SysTick Interrupt.
59         (++) Starts the SysTick Counter.
60 
61    (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
62        __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
63        HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
64        inside the stm32l5xx_hal_cortex.h file.
65 
66    (+) You can change the SysTick IRQ priority by calling the
67        HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
68        call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
69 
70    (+) To adjust the SysTick time base, use the following formula:
71 
72        Reload Value = SysTick Counter Clock (Hz) x  Desired Time base (s)
73        (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
74        (++) Reload Value should not exceed 0xFFFFFF
75 
76   @endverbatim
77   ******************************************************************************
78 
79   The table below gives the allowed values of the pre-emption priority and subpriority according
80   to the Priority Grouping configuration performed by HAL_NVIC_SetPriorityGrouping() function.
81 
82     ==========================================================================================================================
83       NVIC_PriorityGroup   | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority  |       Description
84     ==========================================================================================================================
85      NVIC_PRIORITYGROUP_0  |                0                  |            0-7              | 0 bit for pre-emption priority
86                            |                                   |                             | 3 bits for subpriority
87     --------------------------------------------------------------------------------------------------------------------------
88      NVIC_PRIORITYGROUP_1  |                0-1                |            0-3              | 1 bit for pre-emption priority
89                            |                                   |                             | 2 bits for subpriority
90     --------------------------------------------------------------------------------------------------------------------------
91      NVIC_PRIORITYGROUP_2  |                0-3                |            0-1              | 2 bits for pre-emption priority
92                            |                                   |                             | 1 bits for subpriority
93     --------------------------------------------------------------------------------------------------------------------------
94      NVIC_PRIORITYGROUP_3  |                0-7                |            0                | 3 bits for pre-emption priority
95                            |                                   |                             | 0 bit for subpriority
96     ==========================================================================================================================
97 
98   ******************************************************************************
99   */
100 
101 /* Includes ------------------------------------------------------------------*/
102 #include "stm32l5xx_hal.h"
103 
104 /** @addtogroup STM32L5xx_HAL_Driver
105   * @{
106   */
107 
108 /** @addtogroup CORTEX
109   * @{
110   */
111 
112 #ifdef HAL_CORTEX_MODULE_ENABLED
113 
114 /* Private types -------------------------------------------------------------*/
115 /* Private variables ---------------------------------------------------------*/
116 /* Private constants ---------------------------------------------------------*/
117 /* Private macros ------------------------------------------------------------*/
118 /* Private function prototypes -----------------------------------------------*/
119 /** @defgroup CORTEX_Private_Functions CORTEX Private Functions
120   * @{
121   */
122 #if (__MPU_PRESENT == 1)
123 static void MPU_ConfigRegion(MPU_Type* MPUx, MPU_Region_InitTypeDef *MPU_RegionInit);
124 static void MPU_ConfigMemoryAttributes(MPU_Type* MPUx, MPU_Attributes_InitTypeDef *MPU_AttributesInit);
125 #endif /* __MPU_PRESENT */
126 /**
127   * @}
128   */
129 
130 /* Exported functions --------------------------------------------------------*/
131 
132 /** @addtogroup CORTEX_Exported_Functions
133   * @{
134   */
135 
136 
137 /** @addtogroup CORTEX_Exported_Functions_Group1
138  *  @brief    Initialization and Configuration functions
139  *
140 @verbatim
141   ==============================================================================
142               ##### Initialization and Configuration functions #####
143   ==============================================================================
144     [..]
145       This section provides the CORTEX HAL driver functions allowing to configure Interrupts
146       SysTick functionalities
147 
148 @endverbatim
149   * @{
150   */
151 
152 
153 /**
154   * @brief  Set the priority grouping field (pre-emption priority and subpriority)
155   *         using the required unlock sequence.
156   * @param  PriorityGroup The priority grouping bits length.
157   *         This parameter can be one of the following values:
158   *         @arg NVIC_PRIORITYGROUP_0  0 bit  for pre-emption priority,
159   *                                    3 bits for subpriority
160   *         @arg NVIC_PRIORITYGROUP_1  1 bit  for pre-emption priority,
161   *                                    2 bits for subpriority
162   *         @arg NVIC_PRIORITYGROUP_2  2 bits for pre-emption priority,
163   *                                    1 bits for subpriority
164   *         @arg NVIC_PRIORITYGROUP_3  3 bits for pre-emption priority,
165   *                                    0 bit  for subpriority
166   * @note   When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
167   *         The pending IRQ priority will be managed only by the subpriority.
168   * @retval None
169   */
HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)170 void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
171 {
172   /* Check the parameters */
173   assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
174 
175   /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
176   NVIC_SetPriorityGrouping(PriorityGroup);
177 }
178 
179 /**
180   * @brief  Set the priority of an interrupt.
181   * @param  IRQn External interrupt number.
182   *         This parameter can be an enumerator of IRQn_Type enumeration
183   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l5xxxx.h))
184   * @param  PreemptPriority The pre-emption priority for the IRQn channel.
185   *         This parameter can be a value between 0 and 7
186   *         A lower priority value indicates a higher priority
187   * @param  SubPriority The subpriority level for the IRQ channel.
188   *         This parameter can be a value between 0 and 7
189   *         A lower priority value indicates a higher priority.
190   * @retval None
191   */
HAL_NVIC_SetPriority(IRQn_Type IRQn,uint32_t PreemptPriority,uint32_t SubPriority)192 void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
193 {
194   uint32_t prioritygroup;
195 
196   /* Check the parameters */
197   assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
198   assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
199 
200   prioritygroup = NVIC_GetPriorityGrouping();
201 
202   NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
203 }
204 
205 /**
206   * @brief  Enable a device specific interrupt in the NVIC interrupt controller.
207   * @note   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
208   *         function should be called before.
209   * @param  IRQn External interrupt number.
210   *         This parameter can be an enumerator of IRQn_Type enumeration
211   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l5xxxx.h))
212   * @retval None
213   */
HAL_NVIC_EnableIRQ(IRQn_Type IRQn)214 void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
215 {
216   /* Check the parameters */
217   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
218 
219   /* Enable interrupt */
220   NVIC_EnableIRQ(IRQn);
221 }
222 
223 /**
224   * @brief  Disable a device specific interrupt in the NVIC interrupt controller.
225   * @param  IRQn External interrupt number.
226   *         This parameter can be an enumerator of IRQn_Type enumeration
227   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l5xxxx.h))
228   * @retval None
229   */
HAL_NVIC_DisableIRQ(IRQn_Type IRQn)230 void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
231 {
232   /* Check the parameters */
233   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
234 
235   /* Disable interrupt */
236   NVIC_DisableIRQ(IRQn);
237 }
238 
239 /**
240   * @brief  Initiate a system reset request to reset the MCU.
241   * @retval None
242   */
HAL_NVIC_SystemReset(void)243 void HAL_NVIC_SystemReset(void)
244 {
245   /* System Reset */
246   NVIC_SystemReset();
247 }
248 
249 /**
250   * @brief  Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick):
251   *         Counter is in free running mode to generate periodic interrupts.
252   * @param  TicksNumb Specifies the ticks Number of ticks between two interrupts.
253   * @retval status:  - 0  Function succeeded.
254   *                  - 1  Function failed.
255   */
HAL_SYSTICK_Config(uint32_t TicksNumb)256 uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
257 {
258   return SysTick_Config(TicksNumb);
259 }
260 /**
261   * @}
262   */
263 
264 /** @addtogroup CORTEX_Exported_Functions_Group2
265  *  @brief   Cortex control functions
266  *
267 @verbatim
268   ==============================================================================
269                       ##### Peripheral Control functions #####
270   ==============================================================================
271     [..]
272       This subsection provides a set of functions allowing to control the CORTEX
273       (NVIC, SYSTICK, MPU) functionalities.
274 
275 
276 @endverbatim
277   * @{
278   */
279 
280 /**
281   * @brief  Get the priority grouping field from the NVIC Interrupt Controller.
282   * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
283   */
HAL_NVIC_GetPriorityGrouping(void)284 uint32_t HAL_NVIC_GetPriorityGrouping(void)
285 {
286   /* Get the PRIGROUP[10:8] field value */
287   return NVIC_GetPriorityGrouping();
288 }
289 
290 /**
291   * @brief  Get the priority of an interrupt.
292   * @param  IRQn External interrupt number.
293   *         This parameter can be an enumerator of IRQn_Type enumeration
294   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l5xxxx.h))
295   * @param   PriorityGroup: the priority grouping bits length.
296   *         This parameter can be one of the following values:
297   *           @arg NVIC_PRIORITYGROUP_0  0 bit for pre-emption priority,
298   *                                      3 bits for subpriority
299   *           @arg NVIC_PRIORITYGROUP_1  1 bit for pre-emption priority,
300   *                                      2 bits for subpriority
301   *           @arg NVIC_PRIORITYGROUP_2  2 bits for pre-emption priority,
302   *                                      1 bits for subpriority
303   *           @arg NVIC_PRIORITYGROUP_3  3 bits for pre-emption priority,
304   *                                      0 bit for subpriority
305   * @param  pPreemptPriority Pointer on the Preemptive priority value (starting from 0).
306   * @param  pSubPriority Pointer on the Subpriority value (starting from 0).
307   * @retval None
308   */
HAL_NVIC_GetPriority(IRQn_Type IRQn,uint32_t PriorityGroup,uint32_t * pPreemptPriority,uint32_t * pSubPriority)309 void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
310 {
311   /* Check the parameters */
312   assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
313  /* Get priority for Cortex-M system or device specific interrupts */
314   NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
315 }
316 
317 /**
318   * @brief  Set Pending bit of an external interrupt.
319   * @param  IRQn External interrupt number
320   *         This parameter can be an enumerator of IRQn_Type enumeration
321   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l5xxxx.h))
322   * @retval None
323   */
HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)324 void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
325 {
326   /* Set interrupt pending */
327   NVIC_SetPendingIRQ(IRQn);
328 }
329 
330 /**
331   * @brief  Get Pending Interrupt (read the pending register in the NVIC
332   *         and return the pending bit for the specified interrupt).
333   * @param  IRQn External interrupt number.
334   *          This parameter can be an enumerator of IRQn_Type enumeration
335   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l5xxxx.h))
336   * @retval status: - 0  Interrupt status is not pending.
337   *                 - 1  Interrupt status is pending.
338   */
HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)339 uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
340 {
341   /* Return 1 if pending else 0 */
342   return NVIC_GetPendingIRQ(IRQn);
343 }
344 
345 /**
346   * @brief  Clear the pending bit of an external interrupt.
347   * @param  IRQn External interrupt number.
348   *         This parameter can be an enumerator of IRQn_Type enumeration
349   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l5xxxx.h))
350   * @retval None
351   */
HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)352 void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
353 {
354   /* Clear pending interrupt */
355   NVIC_ClearPendingIRQ(IRQn);
356 }
357 
358 /**
359   * @brief  Get active interrupt (read the active register in NVIC and return the active bit).
360   * @param  IRQn External interrupt number
361   *         This parameter can be an enumerator of IRQn_Type enumeration
362   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l5xxxx.h))
363   * @retval status: - 0  Interrupt status is not pending.
364   *                 - 1  Interrupt status is pending.
365   */
HAL_NVIC_GetActive(IRQn_Type IRQn)366 uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
367 {
368   /* Return 1 if active else 0 */
369   return NVIC_GetActive(IRQn);
370 }
371 
372 /**
373   * @brief  Configure the SysTick clock source.
374   * @param  CLKSource specifies the SysTick clock source.
375   *         This parameter can be one of the following values:
376   *             @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
377   *             @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
378   * @retval None
379   */
HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)380 void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
381 {
382   /* Check the parameters */
383   assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
384   if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
385   {
386     SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
387   }
388   else
389   {
390     SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
391   }
392 }
393 
394 /**
395   * @brief  Handle SYSTICK interrupt request.
396   * @retval None
397   */
HAL_SYSTICK_IRQHandler(void)398 void HAL_SYSTICK_IRQHandler(void)
399 {
400   HAL_SYSTICK_Callback();
401 }
402 
403 /**
404   * @brief  SYSTICK callback.
405   * @retval None
406   */
HAL_SYSTICK_Callback(void)407 __weak void HAL_SYSTICK_Callback(void)
408 {
409   /* NOTE : This function should not be modified, when the callback is needed,
410             the HAL_SYSTICK_Callback could be implemented in the user file
411    */
412 }
413 
414 #if (__MPU_PRESENT == 1)
415 
416 /**
417   * @brief  Enable the MPU.
418   * @param  MPU_Control Specifies the control mode of the MPU during hard fault,
419   *         NMI, FAULTMASK and privileged accessto the default memory
420   *         This parameter can be one of the following values:
421   *            @arg MPU_HFNMI_PRIVDEF_NONE
422   *            @arg MPU_HARDFAULT_NMI
423   *            @arg MPU_PRIVILEGED_DEFAULT
424   *            @arg MPU_HFNMI_PRIVDEF
425   * @retval None
426   */
HAL_MPU_Enable(uint32_t MPU_Control)427 void HAL_MPU_Enable(uint32_t MPU_Control)
428 {
429   /* Enable the MPU */
430   MPU->CTRL   = MPU_Control | MPU_CTRL_ENABLE_Msk;
431 
432   /* Enable fault exceptions */
433   SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
434 
435   /* Follow ARM recommendation with */
436   /* - Data Memory Barrier and Instruction Synchronization to insure MPU usage */
437   __DMB(); /* Force memory writes before continuing */
438   __ISB(); /* Flush and refill pipeline with updated permissions */
439 }
440 
441 /**
442   * @brief  Disable the MPU.
443   * @retval None
444   */
HAL_MPU_Disable(void)445 void HAL_MPU_Disable(void)
446 {
447   __DMB(); /* Force any outstanding transfers to complete before disabling MPU */
448 
449   /* Disable the MPU */
450   MPU->CTRL  &= ~MPU_CTRL_ENABLE_Msk;
451 }
452 
453 /**
454   * @brief  Initialize and configure the Region and the memory to be protected.
455   * @param  MPU_RegionInit Pointer to a MPU_Region_InitTypeDef structure that contains
456   *                        the initialization and configuration information.
457   * @retval None
458   */
HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef * MPU_RegionInit)459 void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_RegionInit)
460 {
461   MPU_ConfigRegion(MPU, MPU_RegionInit);
462 }
463 
464 /**
465   * @brief  Initialize and configure the memory attributes.
466   * @param  MPU_AttributesInit Pointer to a MPU_Attributes_InitTypeDef structure that contains
467   *                            the initialization and configuration information.
468   * @retval None
469   */
HAL_MPU_ConfigMemoryAttributes(MPU_Attributes_InitTypeDef * MPU_AttributesInit)470 void HAL_MPU_ConfigMemoryAttributes(MPU_Attributes_InitTypeDef *MPU_AttributesInit)
471 {
472   MPU_ConfigMemoryAttributes(MPU, MPU_AttributesInit);
473 }
474 
475 #ifdef MPU_NS
476 /**
477   * @brief  Enable the non-secure MPU.
478   * @param  MPU_Control Specifies the control mode of the MPU during hard fault,
479   *         NMI, FAULTMASK and privileged accessto the default memory
480   *         This parameter can be one of the following values:
481   *            @arg MPU_HFNMI_PRIVDEF_NONE
482   *            @arg MPU_HARDFAULT_NMI
483   *            @arg MPU_PRIVILEGED_DEFAULT
484   *            @arg MPU_HFNMI_PRIVDEF
485   * @retval None
486   */
HAL_MPU_Enable_NS(uint32_t MPU_Control)487 void HAL_MPU_Enable_NS(uint32_t MPU_Control)
488 {
489   /* Enable the MPU */
490   MPU_NS->CTRL   = MPU_Control | MPU_CTRL_ENABLE_Msk;
491 
492   /* Enable fault exceptions */
493   SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
494 
495   /* Follow ARM recommendation with */
496   /* - Data Memory Barrier and Instruction Synchronization to insure MPU usage */
497   __DMB(); /* Force memory writes before continuing */
498   __ISB(); /* Flush and refill pipeline with updated permissions */
499 }
500 
501 /**
502   * @brief  Disable the non-secure MPU.
503   * @retval None
504   */
HAL_MPU_Disable_NS(void)505 void HAL_MPU_Disable_NS(void)
506 {
507   __DMB(); /* Force any outstanding transfers to complete before disabling MPU */
508 
509   /* Disable the MPU */
510   MPU_NS->CTRL  &= ~MPU_CTRL_ENABLE_Msk;
511 }
512 
513 /**
514   * @brief  Initialize and configure the Region and the memory to be protected for non-secure MPU.
515   * @param  MPU_RegionInit Pointer to a MPU_Region_InitTypeDef structure that contains
516   *                        the initialization and configuration information.
517   * @retval None
518   */
HAL_MPU_ConfigRegion_NS(MPU_Region_InitTypeDef * MPU_RegionInit)519 void HAL_MPU_ConfigRegion_NS(MPU_Region_InitTypeDef *MPU_RegionInit)
520 {
521   MPU_ConfigRegion(MPU_NS, MPU_RegionInit);
522 }
523 
524 /**
525   * @brief  Initialize and configure the memory attributes for non-secure MPU.
526   * @param  MPU_AttributesInit Pointer to a MPU_Attributes_InitTypeDef structure that contains
527   *                            the initialization and configuration information.
528   * @retval None
529   */
HAL_MPU_ConfigMemoryAttributes_NS(MPU_Attributes_InitTypeDef * MPU_AttributesInit)530 void HAL_MPU_ConfigMemoryAttributes_NS(MPU_Attributes_InitTypeDef *MPU_AttributesInit)
531 {
532   MPU_ConfigMemoryAttributes(MPU_NS, MPU_AttributesInit);
533 }
534 #endif /* MPU_NS */
535 
536 #endif /* __MPU_PRESENT */
537 
538 /**
539   * @}
540   */
541 
542 /**
543   * @}
544   */
545 
546 /* Private functions ---------------------------------------------------------*/
547 /** @addtogroup CORTEX_Private_Functions
548   * @{
549   */
550 
551 #if (__MPU_PRESENT == 1)
552 
MPU_ConfigRegion(MPU_Type * MPUx,MPU_Region_InitTypeDef * MPU_RegionInit)553 static void MPU_ConfigRegion(MPU_Type* MPUx, MPU_Region_InitTypeDef *MPU_RegionInit)
554 {
555   /* Check the parameters */
556   assert_param(IS_MPU_REGION_NUMBER(MPU_RegionInit->Number));
557   assert_param(IS_MPU_REGION_ENABLE(MPU_RegionInit->Enable));
558 
559   /* Follow ARM recommendation with Data Memory Barrier prior to MPU configuration */
560   __DMB();
561 
562   /* Set the Region number */
563   MPUx->RNR = MPU_RegionInit->Number;
564 
565   if (MPU_RegionInit->Enable != MPU_REGION_DISABLE)
566   {
567     /* Check the parameters */
568     assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_RegionInit->DisableExec));
569     assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_RegionInit->AccessPermission));
570     assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_RegionInit->IsShareable));
571 
572     MPUx->RBAR = (((uint32_t)MPU_RegionInit->BaseAddress & 0xFFFFFFE0U)  |
573                   ((uint32_t)MPU_RegionInit->IsShareable      << MPU_RBAR_SH_Pos)  |
574                   ((uint32_t)MPU_RegionInit->AccessPermission << MPU_RBAR_AP_Pos)  |
575                   ((uint32_t)MPU_RegionInit->DisableExec      << MPU_RBAR_XN_Pos));
576 
577     MPUx->RLAR = (((uint32_t)MPU_RegionInit->LimitAddress & 0xFFFFFFE0U) |
578                   ((uint32_t)MPU_RegionInit->AttributesIndex << MPU_RLAR_AttrIndx_Pos) |
579                   ((uint32_t)MPU_RegionInit->Enable          << MPU_RLAR_EN_Pos));
580   }
581   else
582   {
583     MPUx->RLAR = 0U;
584     MPUx->RBAR = 0U;
585   }
586 }
587 
MPU_ConfigMemoryAttributes(MPU_Type * MPUx,MPU_Attributes_InitTypeDef * MPU_AttributesInit)588 static void MPU_ConfigMemoryAttributes(MPU_Type* MPUx, MPU_Attributes_InitTypeDef *MPU_AttributesInit)
589 {
590   __IO uint32_t *mair;
591   uint32_t      attr_values;
592   uint32_t      attr_number;
593 
594   /* Check the parameters */
595   assert_param(IS_MPU_ATTRIBUTES_NUMBER(MPU_AttributesInit->Number));
596   /* No need to check Attributes value as all 0x0..0xFF possible */
597 
598   /* Follow ARM recommendation with Data Memory Barrier prior to MPUx configuration */
599   __DMB();
600 
601   if(MPU_AttributesInit->Number < MPU_ATTRIBUTES_NUMBER4)
602   {
603     /* Program MPU_MAIR0 */
604     mair = &(MPUx->MAIR0);
605     attr_number = MPU_AttributesInit->Number;
606   }
607   else
608   {
609     /* Program MPU_MAIR1 */
610     mair = &(MPUx->MAIR1);
611     attr_number = (uint32_t)MPU_AttributesInit->Number - 4U;
612   }
613 
614   attr_values = *(mair);
615   attr_values &=  ~(0xFFU << (attr_number * 8U));
616   *(mair) = attr_values | ((uint32_t)MPU_AttributesInit->Attributes << (attr_number * 8U));
617 }
618 
619 #endif /* __MPU_PRESENT */
620 
621 /**
622   * @}
623   */
624 
625 #endif /* HAL_CORTEX_MODULE_ENABLED */
626 
627 /**
628   * @}
629   */
630 
631 /**
632   * @}
633   */
634 
635