1 /**
2   ******************************************************************************
3   * @file    stm32g4xx_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
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-M4 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 stm32g4xx_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-15             | 0 bit for pre-emption priority
86                            |                                   |                             | 4 bits for subpriority
87     --------------------------------------------------------------------------------------------------------------------------
88      NVIC_PRIORITYGROUP_1  |                0-1                |            0-7              | 1 bit for pre-emption priority
89                            |                                   |                             | 3 bits for subpriority
90     --------------------------------------------------------------------------------------------------------------------------
91      NVIC_PRIORITYGROUP_2  |                0-3                |            0-3              | 2 bits for pre-emption priority
92                            |                                   |                             | 2 bits for subpriority
93     --------------------------------------------------------------------------------------------------------------------------
94      NVIC_PRIORITYGROUP_3  |                0-7                |            0-1              | 3 bits for pre-emption priority
95                            |                                   |                             | 1 bit for subpriority
96     --------------------------------------------------------------------------------------------------------------------------
97      NVIC_PRIORITYGROUP_4  |                0-15               |            0                | 4 bits for pre-emption priority
98                            |                                   |                             | 0 bit for subpriority
99     ==========================================================================================================================
100 
101   */
102 
103 /* Includes ------------------------------------------------------------------*/
104 #include "stm32g4xx_hal.h"
105 
106 /** @addtogroup STM32G4xx_HAL_Driver
107   * @{
108   */
109 
110 /** @addtogroup CORTEX
111   * @{
112   */
113 
114 #ifdef HAL_CORTEX_MODULE_ENABLED
115 
116 /* Private types -------------------------------------------------------------*/
117 /* Private variables ---------------------------------------------------------*/
118 /* Private constants ---------------------------------------------------------*/
119 /* Private macros ------------------------------------------------------------*/
120 /* Private functions ---------------------------------------------------------*/
121 /* Exported functions --------------------------------------------------------*/
122 
123 /** @addtogroup CORTEX_Exported_Functions
124   * @{
125   */
126 
127 
128 /** @addtogroup CORTEX_Exported_Functions_Group1
129  *  @brief    Initialization and Configuration functions
130  *
131 @verbatim
132   ==============================================================================
133               ##### Initialization and Configuration functions #####
134   ==============================================================================
135     [..]
136       This section provides the CORTEX HAL driver functions allowing to configure Interrupts
137       SysTick functionalities
138 
139 @endverbatim
140   * @{
141   */
142 
143 
144 /**
145   * @brief  Set the priority grouping field (pre-emption priority and subpriority)
146   *         using the required unlock sequence.
147   * @param  PriorityGroup: The priority grouping bits length.
148   *         This parameter can be one of the following values:
149   *         @arg NVIC_PRIORITYGROUP_0: 0 bit  for pre-emption priority,
150   *                                    4 bits for subpriority
151   *         @arg NVIC_PRIORITYGROUP_1: 1 bit  for pre-emption priority,
152   *                                    3 bits for subpriority
153   *         @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority,
154   *                                    2 bits for subpriority
155   *         @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority,
156   *                                    1 bit  for subpriority
157   *         @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority,
158   *                                    0 bit  for subpriority
159   * @note   When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
160   *         The pending IRQ priority will be managed only by the subpriority.
161   * @retval None
162   */
HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)163 void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
164 {
165   /* Check the parameters */
166   assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
167 
168   /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
169   NVIC_SetPriorityGrouping(PriorityGroup);
170 }
171 
172 /**
173   * @brief  Set the priority of an interrupt.
174   * @param  IRQn: External interrupt number.
175   *         This parameter can be an enumerator of IRQn_Type enumeration
176   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32g4xxxx.h))
177   * @param  PreemptPriority: The pre-emption priority for the IRQn channel.
178   *         This parameter can be a value between 0 and 15
179   *         A lower priority value indicates a higher priority
180   * @param  SubPriority: the subpriority level for the IRQ channel.
181   *         This parameter can be a value between 0 and 15
182   *         A lower priority value indicates a higher priority.
183   * @retval None
184   */
HAL_NVIC_SetPriority(IRQn_Type IRQn,uint32_t PreemptPriority,uint32_t SubPriority)185 void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
186 {
187   uint32_t prioritygroup;
188 
189   /* Check the parameters */
190   assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
191   assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
192 
193   prioritygroup = NVIC_GetPriorityGrouping();
194 
195   NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
196 }
197 
198 /**
199   * @brief  Enable a device specific interrupt in the NVIC interrupt controller.
200   * @note   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
201   *         function should be called before.
202   * @param  IRQn External interrupt number.
203   *         This parameter can be an enumerator of IRQn_Type enumeration
204   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32g4xxxx.h))
205   * @retval None
206   */
HAL_NVIC_EnableIRQ(IRQn_Type IRQn)207 void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
208 {
209   /* Check the parameters */
210   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
211 
212   /* Enable interrupt */
213   NVIC_EnableIRQ(IRQn);
214 }
215 
216 /**
217   * @brief  Disable a device specific interrupt in the NVIC interrupt controller.
218   * @param  IRQn External interrupt number.
219   *         This parameter can be an enumerator of IRQn_Type enumeration
220   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32g4xxxx.h))
221   * @retval None
222   */
HAL_NVIC_DisableIRQ(IRQn_Type IRQn)223 void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
224 {
225   /* Check the parameters */
226   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
227 
228   /* Disable interrupt */
229   NVIC_DisableIRQ(IRQn);
230 }
231 
232 /**
233   * @brief  Initiate a system reset request to reset the MCU.
234   * @retval None
235   */
HAL_NVIC_SystemReset(void)236 void HAL_NVIC_SystemReset(void)
237 {
238   /* System Reset */
239   NVIC_SystemReset();
240 }
241 
242 /**
243   * @brief  Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick):
244   *         Counter is in free running mode to generate periodic interrupts.
245   * @param  TicksNumb: Specifies the ticks Number of ticks between two interrupts.
246   * @retval status:  - 0  Function succeeded.
247   *                  - 1  Function failed.
248   */
HAL_SYSTICK_Config(uint32_t TicksNumb)249 uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
250 {
251    return SysTick_Config(TicksNumb);
252 }
253 /**
254   * @}
255   */
256 
257 /** @addtogroup CORTEX_Exported_Functions_Group2
258  *  @brief   Cortex control functions
259  *
260 @verbatim
261   ==============================================================================
262                       ##### Peripheral Control functions #####
263   ==============================================================================
264     [..]
265       This subsection provides a set of functions allowing to control the CORTEX
266       (NVIC, SYSTICK, MPU) functionalities.
267 
268 
269 @endverbatim
270   * @{
271   */
272 
273 /**
274   * @brief  Get the priority grouping field from the NVIC Interrupt Controller.
275   * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
276   */
HAL_NVIC_GetPriorityGrouping(void)277 uint32_t HAL_NVIC_GetPriorityGrouping(void)
278 {
279   /* Get the PRIGROUP[10:8] field value */
280   return NVIC_GetPriorityGrouping();
281 }
282 
283 /**
284   * @brief  Get the priority of an interrupt.
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 to the appropriate CMSIS device file (stm32g4xxxx.h))
288   * @param   PriorityGroup: the priority grouping bits length.
289   *         This parameter can be one of the following values:
290   *           @arg NVIC_PRIORITYGROUP_0: 0 bit for pre-emption priority,
291   *                                      4 bits for subpriority
292   *           @arg NVIC_PRIORITYGROUP_1: 1 bit for pre-emption priority,
293   *                                      3 bits for subpriority
294   *           @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority,
295   *                                      2 bits for subpriority
296   *           @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority,
297   *                                      1 bit for subpriority
298   *           @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority,
299   *                                      0 bit for subpriority
300   * @param  pPreemptPriority: Pointer on the Preemptive priority value (starting from 0).
301   * @param  pSubPriority: Pointer on the Subpriority value (starting from 0).
302   * @retval None
303   */
HAL_NVIC_GetPriority(IRQn_Type IRQn,uint32_t PriorityGroup,uint32_t * pPreemptPriority,uint32_t * pSubPriority)304 void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
305 {
306   /* Check the parameters */
307   assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
308  /* Get priority for Cortex-M system or device specific interrupts */
309   NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
310 }
311 
312 /**
313   * @brief  Set Pending bit of an external interrupt.
314   * @param  IRQn External interrupt number
315   *         This parameter can be an enumerator of IRQn_Type enumeration
316   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32g4xxxx.h))
317   * @retval None
318   */
HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)319 void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
320 {
321   /* Check the parameters */
322   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
323 
324   /* Set interrupt pending */
325   NVIC_SetPendingIRQ(IRQn);
326 }
327 
328 /**
329   * @brief  Get Pending Interrupt (read the pending register in the NVIC
330   *         and return the pending bit for the specified interrupt).
331   * @param  IRQn External interrupt number.
332   *          This parameter can be an enumerator of IRQn_Type enumeration
333   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32g4xxxx.h))
334   * @retval status: - 0  Interrupt status is not pending.
335   *                 - 1  Interrupt status is pending.
336   */
HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)337 uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
338 {
339   /* Check the parameters */
340   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
341 
342   /* Return 1 if pending else 0 */
343   return NVIC_GetPendingIRQ(IRQn);
344 }
345 
346 /**
347   * @brief  Clear the pending bit of an external interrupt.
348   * @param  IRQn External interrupt number.
349   *         This parameter can be an enumerator of IRQn_Type enumeration
350   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32g4xxxx.h))
351   * @retval None
352   */
HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)353 void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
354 {
355   /* Check the parameters */
356   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
357 
358   /* Clear pending interrupt */
359   NVIC_ClearPendingIRQ(IRQn);
360 }
361 
362 /**
363   * @brief Get active interrupt (read the active register in NVIC and return the active bit).
364   * @param IRQn External interrupt number
365   *         This parameter can be an enumerator of IRQn_Type enumeration
366   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32g4xxxx.h))
367   * @retval status: - 0  Interrupt status is not pending.
368   *                 - 1  Interrupt status is pending.
369   */
HAL_NVIC_GetActive(IRQn_Type IRQn)370 uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
371 {
372   /* Return 1 if active else 0 */
373   return NVIC_GetActive(IRQn);
374 }
375 
376 /**
377   * @brief  Configure the SysTick clock source.
378   * @param  CLKSource: specifies the SysTick clock source.
379   *          This parameter can be one of the following values:
380   *             @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
381   *             @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
382   * @retval None
383   */
HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)384 void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
385 {
386   /* Check the parameters */
387   assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
388   if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
389   {
390     SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
391   }
392   else
393   {
394     SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
395   }
396 }
397 
398 /**
399   * @brief  Handle SYSTICK interrupt request.
400   * @retval None
401   */
HAL_SYSTICK_IRQHandler(void)402 void HAL_SYSTICK_IRQHandler(void)
403 {
404   HAL_SYSTICK_Callback();
405 }
406 
407 /**
408   * @brief  SYSTICK callback.
409   * @retval None
410   */
HAL_SYSTICK_Callback(void)411 __weak void HAL_SYSTICK_Callback(void)
412 {
413   /* NOTE : This function should not be modified, when the callback is needed,
414             the HAL_SYSTICK_Callback could be implemented in the user file
415    */
416 }
417 
418 #if (__MPU_PRESENT == 1)
419 /**
420   * @brief  Enable the MPU.
421   * @param  MPU_Control: Specifies the control mode of the MPU during hard fault,
422   *          NMI, FAULTMASK and privileged accessto the default memory
423   *          This parameter can be one of the following values:
424   *            @arg MPU_HFNMI_PRIVDEF_NONE
425   *            @arg MPU_HARDFAULT_NMI
426   *            @arg MPU_PRIVILEGED_DEFAULT
427   *            @arg MPU_HFNMI_PRIVDEF
428   * @retval None
429   */
HAL_MPU_Enable(uint32_t MPU_Control)430 void HAL_MPU_Enable(uint32_t MPU_Control)
431 {
432   /* Enable the MPU */
433   MPU->CTRL = (MPU_Control | MPU_CTRL_ENABLE_Msk);
434 
435   /* Ensure MPU setting take effects */
436   __DSB();
437   __ISB();
438 }
439 
440 
441 /**
442   * @brief  Disable the MPU.
443   * @retval None
444   */
HAL_MPU_Disable(void)445 void HAL_MPU_Disable(void)
446 {
447   /* Make sure outstanding transfers are done */
448   __DMB();
449 
450   /* Disable the MPU and clear the control register*/
451   MPU->CTRL  = 0;
452 }
453 
454 
455 /**
456   * @brief  Initialize and configure the Region and the memory to be protected.
457   * @param  MPU_Init: Pointer to a MPU_Region_InitTypeDef structure that contains
458   *                the initialization and configuration information.
459   * @retval None
460   */
HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef * MPU_Init)461 void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
462 {
463   /* Check the parameters */
464   assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
465   assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
466 
467   /* Set the Region number */
468   MPU->RNR = MPU_Init->Number;
469 
470   if ((MPU_Init->Enable) != 0U)
471   {
472     /* Check the parameters */
473     assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
474     assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
475     assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
476     assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
477     assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
478     assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
479     assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
480     assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
481 
482     MPU->RBAR = MPU_Init->BaseAddress;
483     MPU->RASR = ((uint32_t)MPU_Init->DisableExec        << MPU_RASR_XN_Pos)   |
484                 ((uint32_t)MPU_Init->AccessPermission   << MPU_RASR_AP_Pos)   |
485                 ((uint32_t)MPU_Init->TypeExtField       << MPU_RASR_TEX_Pos)  |
486                 ((uint32_t)MPU_Init->IsShareable        << MPU_RASR_S_Pos)    |
487                 ((uint32_t)MPU_Init->IsCacheable        << MPU_RASR_C_Pos)    |
488                 ((uint32_t)MPU_Init->IsBufferable       << MPU_RASR_B_Pos)    |
489                 ((uint32_t)MPU_Init->SubRegionDisable   << MPU_RASR_SRD_Pos)  |
490                 ((uint32_t)MPU_Init->Size               << MPU_RASR_SIZE_Pos) |
491                 ((uint32_t)MPU_Init->Enable             << MPU_RASR_ENABLE_Pos);
492   }
493   else
494   {
495     MPU->RBAR = 0x00;
496     MPU->RASR = 0x00;
497   }
498 }
499 #endif /* __MPU_PRESENT */
500 
501 /**
502   * @}
503   */
504 
505 /**
506   * @}
507   */
508 
509 #endif /* HAL_CORTEX_MODULE_ENABLED */
510 /**
511   * @}
512   */
513 
514 /**
515   * @}
516   */
517 
518