1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_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) 2023 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     [..]
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-M55 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 (0x0F).
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 stm32n6xx_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     [..]
77     *** How to configure MPU (secure and non secure) using CORTEX HAL driver ***
78     ============================================================================
79     [..]
80     This section provides functions allowing to configure both secure and non-secure MPUs.
81 
82     (#) Enable the MPU using HAL_MPU_Enable() function.
83     (#) Disable the MPU using HAL_MPU_Disable() function.
84     (#) Enable the MPU using HAL_MPU_Enable_NS() function to address the non secure MPU.
85     (#) Disable the MPU using HAL_MPU_Disable_NS() function to address the non secure MPU.
86     (#) Configure the MPU region using HAL_MPU_ConfigRegion()
87         and HAL_MPU_ConfigRegion_NS() to address the non secure MPU.
88     (#) Configure the MPU Memory attributes using HAL_MPU_ConfigMemoryAttributes()
89         and HAL_MPU_ConfigMemoryAttributes_NS() to address the non secure MPU.
90 
91     A device memory has the following attributes:
92     (#) G or nG: gathering or non-gathering. (multiple accesses to a device can be merged into a single
93     transaction except for operations with memory ordering semantics, for example, memory barrier
94     instructions, load acquire/store release).
95     (#) R or nR: reordering
96     (#) E or nE: early write acknowledge (similar to bufferable)
97 
98     Only four combinations of these attributes are valid:
99     (#) device-nGnRnE: equivalent to Armv7-M strongly ordered memory type
100     (#) device-nGnRE: equivalent to Armv7-M device memory
101     (#) device-nGRE: new to Armv8-M
102     (#) device-GRE: new to Armv8-M
103 
104     A normal memory has the following attributes:
105     (#) Cache Allocation attribute : set when a cache line is allocated (no allocation, read/write/read-write allocation)
106     (#) Cache write policy : write through (write to cache AND memory), write back (memory is written when the cache line is evicted)
107     (#) Transient : indicates that the region will be used for a short period of time
108     For normal memory, attributes can be set for inner and outer caches separately.
109     Note that outer attributes set to 0 change the memory to device mode. Both inner and outer attributes should be set for normal memory.
110 
111     Sample configurations
112     (#) Inner-outer cacheable, write back, read-write allocate INNER_OUTER(MPU_RW_ALLOCATE | MPU_WRITE_BACK)
113     (#) Inner write back, read allocation, outer non-cacheable (MPU_R_ALLOCATE | MPU_WRITE_BACK) | OUTER(MPU_NOT_CACHEABLE)
114     For detail on memory attributes, refer to the ARMv8-m MPU documentation.
115 
116     On STM32N6xx, the MPUs are split memory into regions (up to sixteen for both Secure and Non-Secure domains)
117     The secure MPU is only available when TrustZone is activated.
118 
119     (#) Enable the MPU using HAL_MPU_Enable() function or HAL_MPU_Enable_NS function for non-secure MPU.
120     (#) Disable the MPU using HAL_MPU_Disable() function or HAL_MPU_Disable_NS function for non-secure MPU.
121     (#) Enable the MPU region using HAL_MPU_EnableRegion() function or HAL_MPU_EnableRegion_NS function for non-secure MPU region.
122     (#) Disable the MPU region using HAL_MPU_DisableRegion() function or HAL_MPU_DisableRegion_NS function for non-secure MPU region.
123     (#) Configure the MPU region using HAL_MPU_ConfigRegion() function or HAL_MPU_ConfigRegion_NS function
124         for non-secure MPU.
125     (#) Configure the MPU memory attributes using HAL_MPU_ConfigMemoryAttributes() function or
126         HAL_MPU_ConfigMemoryAttributes_NS function for non-secure MPU.
127 
128     (#) The HAL_MPU_XXX_NS functions are only available when TrustZone is activated and CPU in secure state.
129         _NS functions are targeting non secure MPU, in any other cases APIs without NS shall be used.
130 
131   @endverbatim
132   ******************************************************************************
133 
134   The table below gives the allowed values of the pre-emption priority and subpriority according
135   to the Priority Grouping configuration performed by HAL_NVIC_SetPriorityGrouping() function.
136 
137     ==========================================================================================================================
138       NVIC_PriorityGroup   | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority  |       Description
139     ==========================================================================================================================
140      NVIC_PRIORITYGROUP_0  |                0                  |            0-15             | 0 bit for pre-emption priority
141                            |                                   |                             | 4 bits for subpriority
142     --------------------------------------------------------------------------------------------------------------------------
143      NVIC_PRIORITYGROUP_1  |                0-1                |            0-7              | 1 bit for pre-emption priority
144                            |                                   |                             | 3 bits for subpriority
145     --------------------------------------------------------------------------------------------------------------------------
146      NVIC_PRIORITYGROUP_2  |                0-3                |            0-3              | 2 bits for pre-emption priority
147                            |                                   |                             | 2 bits for subpriority
148     --------------------------------------------------------------------------------------------------------------------------
149      NVIC_PRIORITYGROUP_3  |                0-7                |            0-1              | 3 bits for pre-emption priority
150                            |                                   |                             | 1 bit for subpriority
151     --------------------------------------------------------------------------------------------------------------------------
152      NVIC_PRIORITYGROUP_4  |                0-15               |            0                | 4 bits for pre-emption priority
153                            |                                   |                             | 0 bit for subpriority
154     ==========================================================================================================================
155   */
156 
157 /* Includes ------------------------------------------------------------------*/
158 #include "stm32n6xx_hal.h"
159 
160 /** @addtogroup STM32N6xx_HAL_Driver
161   * @{
162   */
163 
164 /** @addtogroup CORTEX
165   * @brief CORTEX HAL module driver
166   * @{
167   */
168 
169 #ifdef HAL_CORTEX_MODULE_ENABLED
170 
171 /* Private types -------------------------------------------------------------*/
172 /* Private variables ---------------------------------------------------------*/
173 /* Private constants ---------------------------------------------------------*/
174 /* Private macros ------------------------------------------------------------*/
175 /* Private functions ---------------------------------------------------------*/
176 /** @defgroup CORTEX_Private_Functions CORTEX Private Functions
177   * @{
178   */
179 static void MPU_ConfigRegion(MPU_Type *MPUx, const MPU_Region_InitTypeDef *pMPU_RegionInit);
180 static void MPU_ConfigMemoryAttributes(MPU_Type *MPUx, const MPU_Attributes_InitTypeDef *pMPU_AttributesInit);
181 /**
182   * @}
183   */
184 
185 /* Exported functions --------------------------------------------------------*/
186 
187 /** @addtogroup CORTEX_Exported_Functions
188   * @{
189   */
190 
191 
192 /** @addtogroup CORTEX_Exported_Functions_Group1
193   *  @brief    Initialization and Configuration functions
194   *
195 @verbatim
196   ==============================================================================
197               ##### Initialization and Configuration functions #####
198   ==============================================================================
199     [..]
200       This section provides the CORTEX HAL driver functions allowing to configure Interrupts
201       SysTick functionalities
202 
203 @endverbatim
204   * @{
205   */
206 
207 
208 /**
209   * @brief  Set the priority grouping field (pre-emption priority and subpriority)
210   *         using the required unlock sequence.
211   * @param  PriorityGroup The priority grouping bits length.
212   *         This parameter can be one of the following values:
213   *         @arg NVIC_PRIORITYGROUP_0  0 bit  for pre-emption priority,
214   *                                    4 bits for subpriority
215   *         @arg NVIC_PRIORITYGROUP_1  1 bit  for pre-emption priority,
216   *                                    3 bits for subpriority
217   *         @arg NVIC_PRIORITYGROUP_2  2 bits for pre-emption priority,
218   *                                    2 bits for subpriority
219   *         @arg NVIC_PRIORITYGROUP_3  3 bits for pre-emption priority,
220   *                                    1 bit  for subpriority
221   *         @arg NVIC_PRIORITYGROUP_4  4 bits for pre-emption priority,
222   *                                    0 bit  for subpriority
223   * @note   When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
224   *         The pending IRQ priority will be managed only by the subpriority.
225   * @retval None
226   */
HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)227 void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
228 {
229   /* Check the parameters */
230   assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
231 
232   /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
233   NVIC_SetPriorityGrouping(PriorityGroup);
234 }
235 
236 /**
237   * @brief  Set the priority of an interrupt.
238   * @param  IRQn External interrupt number.
239   *         This parameter can be an enumerator of IRQn_Type enumeration
240   *         (For the complete STM32 Devices IRQ Channels list, please refer
241   *         to the appropriate CMSIS device file (stm32n6xxxx.h))
242   * @param  PreemptPriority The pre-emption priority for the IRQn channel.
243   *         This parameter can be a value between 0 and 15
244   *         A lower priority value indicates a higher priority
245   * @param  SubPriority the subpriority level for the IRQ channel.
246   *         This parameter can be a value between 0 and 15
247   *         A lower priority value indicates a higher priority.
248   * @retval None
249   */
HAL_NVIC_SetPriority(IRQn_Type IRQn,uint32_t PreemptPriority,uint32_t SubPriority)250 void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
251 {
252   uint32_t prioritygroup;
253 
254   /* Check the parameters */
255   assert_param(IS_NVIC_PRIORITY_INTERRUPT(IRQn));
256 
257   prioritygroup = (NVIC_GetPriorityGrouping() & 0x7U);
258   assert_param(IS_NVIC_SUB_PRIORITY(SubPriority, prioritygroup));
259   assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority, prioritygroup));
260 
261   NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
262 }
263 
264 /**
265   * @brief  Enable a device specific interrupt in the NVIC interrupt controller.
266   * @note   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
267   *         function should be called before.
268   * @param  IRQn External interrupt number.
269   *         This parameter can be an enumerator of IRQn_Type enumeration
270   *         (For the complete STM32 Devices IRQ Channels list, please refer
271   *         to the appropriate CMSIS device file (stm32n6xxxx.h))
272   * @retval None
273   */
HAL_NVIC_EnableIRQ(IRQn_Type IRQn)274 void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
275 {
276   /* Check the parameters */
277   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
278 
279   /* Enable interrupt */
280   NVIC_EnableIRQ(IRQn);
281 }
282 
283 /**
284   * @brief  Disable a device specific interrupt in the NVIC interrupt controller.
285   * @param  IRQn External interrupt number.
286   *         This parameter can be an enumerator of IRQn_Type enumeration
287   *         (For the complete STM32 Devices IRQ Channels list, please refer
288   *         to the appropriate CMSIS device file (stm32n6xxxx.h))
289   * @retval None
290   */
HAL_NVIC_DisableIRQ(IRQn_Type IRQn)291 void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
292 {
293   /* Check the parameters */
294   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
295 
296   /* Disable interrupt */
297   NVIC_DisableIRQ(IRQn);
298 }
299 
300 /**
301   * @brief  Initiate a system reset request to reset the MCU.
302   * @retval None
303   */
HAL_NVIC_SystemReset(void)304 void HAL_NVIC_SystemReset(void)
305 {
306   /* System Reset */
307   NVIC_SystemReset();
308 }
309 
310 /**
311   * @brief  Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick):
312   *         Counter is in free running mode to generate periodic interrupts.
313   * @param  TicksNumb Specifies the ticks Number of ticks between two interrupts.
314   * @retval status:  - 0  Function succeeded.
315   *                  - 1  Function failed.
316   */
HAL_SYSTICK_Config(uint32_t TicksNumb)317 uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
318 {
319   return SysTick_Config(TicksNumb);
320 }
321 /**
322   * @}
323   */
324 
325 /** @addtogroup CORTEX_Exported_Functions_Group2
326   *  @brief   Cortex control functions
327   *
328 @verbatim
329   ==============================================================================
330                       ##### Peripheral Control functions #####
331   ==============================================================================
332     [..]
333       This subsection provides a set of functions allowing to control the CORTEX
334       (NVIC, SYSTICK, MPU) functionalities.
335 
336 
337 @endverbatim
338   * @{
339   */
340 
341 /**
342   * @brief  Get the priority grouping field from the NVIC Interrupt Controller.
343   * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
344   */
HAL_NVIC_GetPriorityGrouping(void)345 uint32_t HAL_NVIC_GetPriorityGrouping(void)
346 {
347   /* Get the PRIGROUP[10:8] field value */
348   return NVIC_GetPriorityGrouping();
349 }
350 
351 /**
352   * @brief  Get the priority of an interrupt.
353   * @param  IRQn External interrupt number.
354   *         This parameter can be an enumerator of IRQn_Type enumeration
355   *         (For the complete STM32 Devices IRQ Channels list, please refer
356   *         to the appropriate CMSIS device file (stm32n6xxxx.h))
357   * @param   PriorityGroup the priority grouping bits length.
358   *         This parameter can be one of the following values:
359   *           @arg NVIC_PRIORITYGROUP_0  0 bit for pre-emption priority,
360   *                                      4 bits for subpriority
361   *           @arg NVIC_PRIORITYGROUP_1  1 bit for pre-emption priority,
362   *                                      3 bits for subpriority
363   *           @arg NVIC_PRIORITYGROUP_2  2 bits for pre-emption priority,
364   *                                      2 bits for subpriority
365   *           @arg NVIC_PRIORITYGROUP_3  3 bits for pre-emption priority,
366   *                                      1 bit for subpriority
367   *           @arg NVIC_PRIORITYGROUP_4  4 bits for pre-emption priority,
368   *                                      0 bit for subpriority
369   * @param  pPreemptPriority Pointer on the Preemptive priority value (starting from 0).
370   * @param  pSubPriority Pointer on the Subpriority value (starting from 0).
371   * @retval None
372   */
HAL_NVIC_GetPriority(IRQn_Type IRQn,uint32_t PriorityGroup,uint32_t * pPreemptPriority,uint32_t * pSubPriority)373 void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
374 {
375   /* Check the parameters */
376   assert_param(IS_NVIC_PRIORITY_INTERRUPT(IRQn));
377   assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
378 
379   /* Get priority for Cortex-M system or device specific interrupts */
380   NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
381 }
382 
383 /**
384   * @brief  Set Pending bit of an external interrupt.
385   * @param  IRQn External interrupt number
386   *         This parameter can be an enumerator of IRQn_Type enumeration
387   *         (For the complete STM32 Devices IRQ Channels list, please refer
388   *         to the appropriate CMSIS device file (stm32n6xxxx.h))
389   * @retval None
390   */
HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)391 void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
392 {
393   /* Check the parameters */
394   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
395 
396   /* Set interrupt pending */
397   NVIC_SetPendingIRQ(IRQn);
398 }
399 
400 /**
401   * @brief  Get Pending Interrupt (read the pending register in the NVIC
402   *         and return the pending bit for the specified interrupt).
403   * @param  IRQn External interrupt number.
404   *         This parameter can be an enumerator of IRQn_Type enumeration
405   *         (For the complete STM32 Devices IRQ Channels list, please refer
406   *         to the appropriate CMSIS device file (stm32n6xxxx.h))
407   * @retval status: - 0  Interrupt status is not pending.
408   *                 - 1  Interrupt status is pending.
409   */
HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)410 uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
411 {
412   /* Check the parameters */
413   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
414 
415   /* Return 1 if pending else 0 */
416   return NVIC_GetPendingIRQ(IRQn);
417 }
418 
419 /**
420   * @brief  Clear the pending bit of an external interrupt.
421   * @param  IRQn External interrupt number.
422   *         This parameter can be an enumerator of IRQn_Type enumeration
423   *         (For the complete STM32 Devices IRQ Channels list, please refer
424   *         to the appropriate CMSIS device file (stm32n6xxxx.h))
425   * @retval None
426   */
HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)427 void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
428 {
429   /* Check the parameters */
430   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
431 
432   /* Clear pending interrupt */
433   NVIC_ClearPendingIRQ(IRQn);
434 }
435 
436 /**
437   * @brief  Get active interrupt (read the active register in NVIC and return the active bit).
438   * @param  IRQn External interrupt number
439   *         This parameter can be an enumerator of IRQn_Type enumeration
440   *         (For the complete STM32 Devices IRQ Channels list, please refer
441   *         to the appropriate CMSIS device file (stm32n6xxxx.h))
442   * @retval status: - 0  Interrupt status is not pending.
443   *                 - 1  Interrupt status is pending.
444   */
HAL_NVIC_GetActive(IRQn_Type IRQn)445 uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
446 {
447   /* Return 1 if active else 0 */
448   return NVIC_GetActive(IRQn);
449 }
450 
451 /**
452   * @brief  Configure the SysTick clock source.
453   * @param  CLKSource specifies the SysTick clock source.
454   *         This parameter can be one of the following values:
455   *             @arg SYSTICK_CLKSOURCE_HCLK AHB clock selected as SysTick clock source.
456   *             @arg SYSTICK_CLKSOURCE_HCLK_DIV8 AHB clock divided by 8 selected as SysTick clock source.
457   * @retval None
458   */
HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)459 void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
460 {
461   /* Check the parameters */
462   assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
463 
464   MODIFY_REG(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk, CLKSource);
465 }
466 
467 /**
468   * @brief  Handle SYSTICK interrupt request.
469   * @retval None
470   */
HAL_SYSTICK_IRQHandler(void)471 void HAL_SYSTICK_IRQHandler(void)
472 {
473   HAL_SYSTICK_Callback();
474 }
475 
476 /**
477   * @brief  SYSTICK callback.
478   * @retval None
479   */
HAL_SYSTICK_Callback(void)480 __weak void HAL_SYSTICK_Callback(void)
481 {
482   /* NOTE : This function should not be modified, when the callback is needed,
483             the HAL_SYSTICK_Callback could be implemented in the user file
484    */
485 }
486 
487 /**
488   * @brief  Clear pending event(s).
489   * @retval None
490   */
HAL_CORTEX_ClearEvent(void)491 void HAL_CORTEX_ClearEvent(void)
492 {
493   __SEV();
494   __WFE();
495 }
496 
497 /**
498   * @brief  Enable the MPU.
499   * @param  MPU_Control Specifies the control mode of the MPU during hard fault,
500   *                     NMI, FAULTMASK and privileged access to the default memory
501   *         This parameter can be one of the following values:
502   *            @arg MPU_HFNMI_PRIVDEF_NONE
503   *            @arg MPU_HARDFAULT_NMI
504   *            @arg MPU_PRIVILEGED_DEFAULT
505   *            @arg MPU_HFNMI_PRIVDEF
506   * @retval None
507   */
HAL_MPU_Enable(uint32_t MPU_Control)508 void HAL_MPU_Enable(uint32_t MPU_Control)
509 {
510   __DMB(); /* Force any outstanding transfers to complete before enabling MPU */
511 
512   /* Enable the MPU */
513   MPU->CTRL = (MPU_Control | MPU_CTRL_ENABLE_Msk);
514 
515   /* Enable fault exceptions */
516   SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
517 
518   /* Ensure MPU setting take effects */
519   __DSB();
520   __ISB();
521 }
522 
523 #if defined (CPU_IN_SECURE_STATE)
524 /**
525   * @brief  Enable the non-secure MPU.
526   * @param  MPU_Control: Specifies the control mode of the MPU during hard fault,
527   *                      NMI, FAULTMASK and privileged access to the default memory
528   *          This parameter can be one of the following values:
529   *            @arg MPU_HFNMI_PRIVDEF_NONE
530   *            @arg MPU_HARDFAULT_NMI
531   *            @arg MPU_PRIVILEGED_DEFAULT
532   *            @arg MPU_HFNMI_PRIVDEF
533   * @retval None
534   */
HAL_MPU_Enable_NS(uint32_t MPU_Control)535 void HAL_MPU_Enable_NS(uint32_t MPU_Control)
536 {
537   __DMB(); /* Force any outstanding transfers to complete before enabling MPU */
538 
539   /* Enable the MPU */
540   MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
541 
542   /* Enable fault exceptions */
543   SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
544 
545   /* Ensure MPU setting take effects */
546   __DSB();
547   __ISB();
548 }
549 #endif /* CPU_IN_SECURE_STATE */
550 
551 /**
552   * @brief  Disable the MPU.
553   * @retval None
554   */
HAL_MPU_Disable(void)555 void HAL_MPU_Disable(void)
556 {
557   __DMB(); /* Force any outstanding transfers to complete before disabling MPU */
558 
559   /* Disable fault exceptions */
560   SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
561 
562   /* Disable the MPU */
563   MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
564 
565   /* Ensure MPU setting take effects */
566   __DSB();
567   __ISB();
568 }
569 
570 #if defined (CPU_IN_SECURE_STATE)
571 /**
572   * @brief  Disable the non-secure MPU.
573   * @retval None
574   */
HAL_MPU_Disable_NS(void)575 void HAL_MPU_Disable_NS(void)
576 {
577   __DMB(); /* Force any outstanding transfers to complete before disabling MPU */
578 
579   /* Disable fault exceptions */
580   SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
581 
582   /* Disable the MPU */
583   MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
584 
585   /* Ensure MPU setting take effects */
586   __DSB();
587   __ISB();
588 }
589 #endif /* CPU_IN_SECURE_STATE */
590 
591 /**
592   * @brief  Enable the MPU Region.
593   * @retval None
594   */
HAL_MPU_EnableRegion(uint32_t RegionNumber)595 void HAL_MPU_EnableRegion(uint32_t RegionNumber)
596 {
597   /* Check the parameters */
598   assert_param(IS_MPU_REGION_NUMBER(RegionNumber));
599 
600   /* Set the Region number */
601   MPU->RNR = RegionNumber;
602 
603   /* Enable the Region */
604   SET_BIT(MPU->RLAR, MPU_RLAR_EN_Msk);
605 }
606 
607 #if defined (CPU_IN_SECURE_STATE)
608 /**
609   * @brief  Enable the non-secure MPU Region.
610   * @retval None
611   */
HAL_MPU_EnableRegion_NS(uint32_t RegionNumber)612 void HAL_MPU_EnableRegion_NS(uint32_t RegionNumber)
613 {
614   assert_param(IS_MPU_REGION_NUMBER(RegionNumber));
615 
616   /* Set the Region number */
617   MPU_NS->RNR = RegionNumber;
618 
619   /* Enable the Region */
620   SET_BIT(MPU_NS->RLAR, MPU_RLAR_EN_Msk);
621 }
622 #endif /* CPU_IN_SECURE_STATE */
623 
624 /**
625   * @brief  Disable the MPU Region.
626   * @retval None
627   */
HAL_MPU_DisableRegion(uint32_t RegionNumber)628 void HAL_MPU_DisableRegion(uint32_t RegionNumber)
629 {
630   /* Check the parameters */
631   assert_param(IS_MPU_REGION_NUMBER(RegionNumber));
632 
633   /* Set the Region number */
634   MPU->RNR = RegionNumber;
635 
636   /* Disable the Region */
637   CLEAR_BIT(MPU->RLAR, MPU_RLAR_EN_Msk);
638 }
639 
640 #if defined (CPU_IN_SECURE_STATE)
641 /**
642   * @brief  Disable the non-secure MPU Region.
643   * @retval None
644   */
HAL_MPU_DisableRegion_NS(uint32_t RegionNumber)645 void HAL_MPU_DisableRegion_NS(uint32_t RegionNumber)
646 {
647   /* Check the parameters */
648   assert_param(IS_MPU_REGION_NUMBER(RegionNumber));
649 
650   /* Set the Region number */
651   MPU_NS->RNR = RegionNumber;
652 
653   /* Disable the Region */
654   CLEAR_BIT(MPU_NS->RLAR, MPU_RLAR_EN_Msk);
655 }
656 #endif /* CPU_IN_SECURE_STATE */
657 
658 
659 /**
660   * @brief  Initialize and configure the Region and the memory to be protected.
661   * @param  pMPU_RegionInit Pointer to a MPU_Region_InitTypeDef structure that contains
662   *                         the initialization and configuration information.
663   * @retval None
664   */
HAL_MPU_ConfigRegion(const MPU_Region_InitTypeDef * pMPU_RegionInit)665 void HAL_MPU_ConfigRegion(const MPU_Region_InitTypeDef *pMPU_RegionInit)
666 {
667   MPU_ConfigRegion(MPU, pMPU_RegionInit);
668 }
669 
670 #if defined (CPU_IN_SECURE_STATE)
671 /**
672   * @brief  Initialize and configure the Region and the memory to be protected for non-secure MPU.
673   * @param  pMPU_RegionInit Pointer to a MPU_Region_InitTypeDef structure that contains
674   *                         the initialization and configuration information.
675   * @retval None
676   */
HAL_MPU_ConfigRegion_NS(const MPU_Region_InitTypeDef * pMPU_RegionInit)677 void HAL_MPU_ConfigRegion_NS(const MPU_Region_InitTypeDef *pMPU_RegionInit)
678 {
679   MPU_ConfigRegion(MPU_NS, pMPU_RegionInit);
680 }
681 #endif /* CPU_IN_SECURE_STATE */
682 
683 /**
684   * @brief  Initialize and configure the memory attributes.
685   * @param  pMPU_AttributesInit Pointer to a MPU_Attributes_InitTypeDef structure that contains
686   *                             the initialization and configuration information.
687   * @retval None
688   */
HAL_MPU_ConfigMemoryAttributes(const MPU_Attributes_InitTypeDef * pMPU_AttributesInit)689 void HAL_MPU_ConfigMemoryAttributes(const MPU_Attributes_InitTypeDef *pMPU_AttributesInit)
690 {
691   MPU_ConfigMemoryAttributes(MPU, pMPU_AttributesInit);
692 }
693 
694 #if defined (CPU_IN_SECURE_STATE)
695 /**
696   * @brief  Initialize and configure the memory attributes for non-secure MPU.
697   * @param  pMPU_AttributesInit Pointer to a MPU_Attributes_InitTypeDef structure that contains
698   *                             the initialization and configuration information.
699   * @retval None
700   */
HAL_MPU_ConfigMemoryAttributes_NS(const MPU_Attributes_InitTypeDef * pMPU_AttributesInit)701 void HAL_MPU_ConfigMemoryAttributes_NS(const MPU_Attributes_InitTypeDef *pMPU_AttributesInit)
702 {
703   MPU_ConfigMemoryAttributes(MPU_NS, pMPU_AttributesInit);
704 }
705 #endif /* CPU_IN_SECURE_STATE */
706 
707 /**
708   * @}
709   */
710 
711 /**
712   * @}
713   */
714 
715 /** @addtogroup CORTEX_Private_Functions
716   * @{
717   */
MPU_ConfigRegion(MPU_Type * MPUx,const MPU_Region_InitTypeDef * pMPU_RegionInit)718 static void MPU_ConfigRegion(MPU_Type *MPUx, const MPU_Region_InitTypeDef *pMPU_RegionInit)
719 {
720   /* Check the parameters */
721   assert_param(IS_MPU_REGION_NUMBER(pMPU_RegionInit->Number));
722   assert_param(IS_MPU_REGION_ENABLE(pMPU_RegionInit->Enable));
723 
724   /* Set the Region number */
725   MPUx->RNR = pMPU_RegionInit->Number;
726 
727   /* Disable the Region */
728   CLEAR_BIT(MPUx->RLAR, MPU_RLAR_EN_Msk);
729 
730   /* Check the parameters */
731   assert_param(IS_MPU_INSTRUCTION_ACCESS(pMPU_RegionInit->DisableExec));
732   assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(pMPU_RegionInit->AccessPermission));
733   assert_param(IS_MPU_ACCESS_SHAREABLE(pMPU_RegionInit->IsShareable));
734   assert_param(IS_MPU_ATTRIBUTES_NUMBER(pMPU_RegionInit->AttributesIndex));
735 
736   MPUx->RBAR = (((uint32_t)pMPU_RegionInit->BaseAddress & 0xFFFFFFE0UL)  |
737                 ((uint32_t)pMPU_RegionInit->IsShareable      << MPU_RBAR_SH_Pos)  |
738                 ((uint32_t)pMPU_RegionInit->AccessPermission << MPU_RBAR_AP_Pos)  |
739                 ((uint32_t)pMPU_RegionInit->DisableExec      << MPU_RBAR_XN_Pos));
740 
741   MPUx->RLAR = (((uint32_t)pMPU_RegionInit->LimitAddress & 0xFFFFFFE0UL) |
742                 ((uint32_t)pMPU_RegionInit->AttributesIndex  << MPU_RLAR_AttrIndx_Pos) |
743                 ((uint32_t)pMPU_RegionInit->Enable           << MPU_RLAR_EN_Pos));
744 }
745 
MPU_ConfigMemoryAttributes(MPU_Type * MPUx,const MPU_Attributes_InitTypeDef * pMPU_AttributesInit)746 static void MPU_ConfigMemoryAttributes(MPU_Type *MPUx, const MPU_Attributes_InitTypeDef *pMPU_AttributesInit)
747 {
748   __IO uint32_t *p_mair;
749   uint32_t      attr_values;
750   uint32_t      attr_number;
751 
752   /* Check the parameters */
753   assert_param(IS_MPU_ATTRIBUTES_NUMBER(pMPU_AttributesInit->Number));
754   /* No need to check Attributes value as all 0x0..0xFF possible */
755 
756   if (pMPU_AttributesInit->Number < MPU_ATTRIBUTES_NUMBER4)
757   {
758     /* Program MPU_MAIR0 */
759     p_mair = &(MPUx->MAIR0);
760     attr_number = pMPU_AttributesInit->Number;
761   }
762   else
763   {
764     /* Program MPU_MAIR1 */
765     p_mair = &(MPUx->MAIR1);
766     attr_number = (uint32_t)pMPU_AttributesInit->Number - 4U;
767   }
768 
769   attr_values = *(p_mair);
770   attr_values &=  ~(0xFFU << (attr_number * 8U));
771   *(p_mair) = attr_values | ((uint32_t)pMPU_AttributesInit->Attributes << (attr_number * 8U));
772 }
773 
774 /**
775   * @}
776   */
777 
778 #endif /* HAL_CORTEX_MODULE_ENABLED */
779 
780 /**
781   * @}
782   */
783 
784 /**
785   * @}
786   */
787