/ Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_hal_cortex.c
stm32f4xx_hal_cortex.c
  1  /**
  2    ******************************************************************************
  3    * @file    stm32f4xx_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 de-initialization functions
  9    *           + Peripheral Control functions 
 10    *
 11    @verbatim  
 12    ==============================================================================
 13                          ##### How to use this driver #####
 14    ==============================================================================
 15  
 16      [..]  
 17      *** How to configure Interrupts using CORTEX HAL driver ***
 18      ===========================================================
 19      [..]     
 20      This section provides functions allowing to configure the NVIC interrupts (IRQ).
 21      The Cortex-M4 exceptions are managed by CMSIS functions.
 22     
 23      (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
 24          function according to the following table.
 25      (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority(). 
 26      (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
 27      (#) please refer to programming manual for details in how to configure priority. 
 28        
 29       -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible. 
 30           The pending IRQ priority will be managed only by the sub priority.
 31     
 32       -@- IRQ priority order (sorted by highest to lowest priority):
 33          (+@) Lowest preemption priority
 34          (+@) Lowest sub priority
 35          (+@) Lowest hardware priority (IRQ number)
 36   
 37      [..]  
 38      *** How to configure Systick using CORTEX HAL driver ***
 39      ========================================================
 40      [..]
 41      Setup SysTick Timer for time base.
 42             
 43     (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which
 44         is a CMSIS function that:
 45          (++) Configures the SysTick Reload register with value passed as function parameter.
 46          (++) Configures the SysTick IRQ priority to the lowest value 0x0F.
 47          (++) Resets the SysTick Counter register.
 48          (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
 49          (++) Enables the SysTick Interrupt.
 50          (++) Starts the SysTick Counter.
 51      
 52     (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
 53         __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
 54         HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
 55         inside the stm32f4xx_hal_cortex.h file.
 56  
 57     (+) You can change the SysTick IRQ priority by calling the
 58         HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function 
 59         call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
 60  
 61     (+) To adjust the SysTick time base, use the following formula:
 62                              
 63         Reload Value = SysTick Counter Clock (Hz) x  Desired Time base (s)
 64         (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
 65         (++) Reload Value should not exceed 0xFFFFFF
 66     
 67    @endverbatim
 68    ******************************************************************************
 69    * @attention
 70    *
 71    * Copyright (c) 2017 STMicroelectronics.
 72    * All rights reserved.
 73    *
 74    * This software is licensed under terms that can be found in the LICENSE file in
 75    * the root directory of this software component.
 76    * If no LICENSE file comes with this software, it is provided AS-IS.
 77    ******************************************************************************
 78    */
 79  
 80  /* Includes ------------------------------------------------------------------*/
 81  #include "stm32f4xx_hal.h"
 82  
 83  /** @addtogroup STM32F4xx_HAL_Driver
 84    * @{
 85    */
 86  
 87  /** @defgroup CORTEX CORTEX
 88    * @brief CORTEX HAL module driver
 89    * @{
 90    */
 91  
 92  #ifdef HAL_CORTEX_MODULE_ENABLED
 93  
 94  /* Private types -------------------------------------------------------------*/
 95  /* Private variables ---------------------------------------------------------*/
 96  /* Private constants ---------------------------------------------------------*/
 97  /* Private macros ------------------------------------------------------------*/
 98  /* Private functions ---------------------------------------------------------*/
 99  /* Exported functions --------------------------------------------------------*/
100  
101  /** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
102    * @{
103    */
104  
105  
106  /** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
107   *  @brief    Initialization and Configuration functions 
108   *
109  @verbatim    
110    ==============================================================================
111                ##### Initialization and de-initialization functions #####
112    ==============================================================================
113      [..]
114        This section provides the CORTEX HAL driver functions allowing to configure Interrupts
115        Systick functionalities 
116  
117  @endverbatim
118    * @{
119    */
120  
121  
122  /**
123    * @brief  Sets the priority grouping field (preemption priority and subpriority)
124    *         using the required unlock sequence.
125    * @param  PriorityGroup The priority grouping bits length. 
126    *         This parameter can be one of the following values:
127    *         @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
128    *                                    4 bits for subpriority
129    *         @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
130    *                                    3 bits for subpriority
131    *         @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
132    *                                    2 bits for subpriority
133    *         @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
134    *                                    1 bits for subpriority
135    *         @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
136    *                                    0 bits for subpriority
137    * @note   When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible. 
138    *         The pending IRQ priority will be managed only by the subpriority. 
139    * @retval None
140    */
141  void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
142  {
143    /* Check the parameters */
144    assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
145    
146    /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
147    NVIC_SetPriorityGrouping(PriorityGroup);
148  }
149  
150  /**
151    * @brief  Sets the priority of an interrupt.
152    * @param  IRQn External interrupt number.
153    *         This parameter can be an enumerator of IRQn_Type enumeration
154    *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
155    * @param  PreemptPriority The preemption priority for the IRQn channel.
156    *         This parameter can be a value between 0 and 15
157    *         A lower priority value indicates a higher priority 
158    * @param  SubPriority the subpriority level for the IRQ channel.
159    *         This parameter can be a value between 0 and 15
160    *         A lower priority value indicates a higher priority.          
161    * @retval None
162    */
163  void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
164  { 
165    uint32_t prioritygroup = 0x00U;
166    
167    /* Check the parameters */
168    assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
169    assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
170    
171    prioritygroup = NVIC_GetPriorityGrouping();
172    
173    NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
174  }
175  
176  /**
177    * @brief  Enables a device specific interrupt in the NVIC interrupt controller.
178    * @note   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
179    *         function should be called before. 
180    * @param  IRQn External interrupt number.
181    *         This parameter can be an enumerator of IRQn_Type enumeration
182    *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
183    * @retval None
184    */
185  void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
186  {
187    /* Check the parameters */
188    assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
189    
190    /* Enable interrupt */
191    NVIC_EnableIRQ(IRQn);
192  }
193  
194  /**
195    * @brief  Disables a device specific interrupt in the NVIC interrupt controller.
196    * @param  IRQn External interrupt number.
197    *         This parameter can be an enumerator of IRQn_Type enumeration
198    *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
199    * @retval None
200    */
201  void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
202  {
203    /* Check the parameters */
204    assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
205    
206    /* Disable interrupt */
207    NVIC_DisableIRQ(IRQn);
208  }
209  
210  /**
211    * @brief  Initiates a system reset request to reset the MCU.
212    * @retval None
213    */
214  void HAL_NVIC_SystemReset(void)
215  {
216    /* System Reset */
217    NVIC_SystemReset();
218  }
219  
220  /**
221    * @brief  Initializes the System Timer and its interrupt, and starts the System Tick Timer.
222    *         Counter is in free running mode to generate periodic interrupts.
223    * @param  TicksNumb Specifies the ticks Number of ticks between two interrupts.
224    * @retval status:  - 0  Function succeeded.
225    *                  - 1  Function failed.
226    */
227  uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
228  {
229     return SysTick_Config(TicksNumb);
230  }
231  /**
232    * @}
233    */
234  
235  /** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
236   *  @brief   Cortex control functions 
237   *
238  @verbatim   
239    ==============================================================================
240                        ##### Peripheral Control functions #####
241    ==============================================================================  
242      [..]
243        This subsection provides a set of functions allowing to control the CORTEX
244        (NVIC, SYSTICK, MPU) functionalities. 
245   
246        
247  @endverbatim
248    * @{
249    */
250  
251  #if (__MPU_PRESENT == 1U)
252  /**
253    * @brief  Disables the MPU
254    * @retval None
255    */
256  void HAL_MPU_Disable(void)
257  {
258    /* Make sure outstanding transfers are done */
259    __DMB();
260  
261    /* Disable fault exceptions */
262    SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
263    
264    /* Disable the MPU and clear the control register*/
265    MPU->CTRL = 0U;
266  }
267  
268  /**
269    * @brief  Enable the MPU.
270    * @param  MPU_Control Specifies the control mode of the MPU during hard fault, 
271    *          NMI, FAULTMASK and privileged access to the default memory 
272    *          This parameter can be one of the following values:
273    *            @arg MPU_HFNMI_PRIVDEF_NONE
274    *            @arg MPU_HARDFAULT_NMI
275    *            @arg MPU_PRIVILEGED_DEFAULT
276    *            @arg MPU_HFNMI_PRIVDEF
277    * @retval None
278    */
279  void HAL_MPU_Enable(uint32_t MPU_Control)
280  {
281    /* Enable the MPU */
282    MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
283    
284    /* Enable fault exceptions */
285    SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
286    
287    /* Ensure MPU setting take effects */
288    __DSB();
289    __ISB();
290  }
291  
292  /**
293    * @brief  Initializes and configures the Region and the memory to be protected.
294    * @param  MPU_Init Pointer to a MPU_Region_InitTypeDef structure that contains
295    *                the initialization and configuration information.
296    * @retval None
297    */
298  void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
299  {
300    /* Check the parameters */
301    assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
302    assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
303  
304    /* Set the Region number */
305    MPU->RNR = MPU_Init->Number;
306  
307    if ((MPU_Init->Enable) != RESET)
308    {
309      /* Check the parameters */
310      assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
311      assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
312      assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
313      assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
314      assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
315      assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
316      assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
317      assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
318      
319      MPU->RBAR = MPU_Init->BaseAddress;
320      MPU->RASR = ((uint32_t)MPU_Init->DisableExec             << MPU_RASR_XN_Pos)   |
321                  ((uint32_t)MPU_Init->AccessPermission        << MPU_RASR_AP_Pos)   |
322                  ((uint32_t)MPU_Init->TypeExtField            << MPU_RASR_TEX_Pos)  |
323                  ((uint32_t)MPU_Init->IsShareable             << MPU_RASR_S_Pos)    |
324                  ((uint32_t)MPU_Init->IsCacheable             << MPU_RASR_C_Pos)    |
325                  ((uint32_t)MPU_Init->IsBufferable            << MPU_RASR_B_Pos)    |
326                  ((uint32_t)MPU_Init->SubRegionDisable        << MPU_RASR_SRD_Pos)  |
327                  ((uint32_t)MPU_Init->Size                    << MPU_RASR_SIZE_Pos) |
328                  ((uint32_t)MPU_Init->Enable                  << MPU_RASR_ENABLE_Pos);
329    }
330    else
331    {
332      MPU->RBAR = 0x00U;
333      MPU->RASR = 0x00U;
334    }
335  }
336  #endif /* __MPU_PRESENT */
337  
338  /**
339    * @brief  Clear pending events.
340    * @retval None
341    */
342  void HAL_CORTEX_ClearEvent(void)
343  {
344    __SEV();
345    __WFE();
346  }
347  
348  /**
349    * @brief  Gets the priority grouping field from the NVIC Interrupt Controller.
350    * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
351    */
352  uint32_t HAL_NVIC_GetPriorityGrouping(void)
353  {
354    /* Get the PRIGROUP[10:8] field value */
355    return NVIC_GetPriorityGrouping();
356  }
357  
358  /**
359    * @brief  Gets the priority of an interrupt.
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 (stm32f4xxxx.h))
363    * @param   PriorityGroup the priority grouping bits length.
364    *         This parameter can be one of the following values:
365    *           @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
366    *                                      4 bits for subpriority
367    *           @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
368    *                                      3 bits for subpriority
369    *           @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
370    *                                      2 bits for subpriority
371    *           @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
372    *                                      1 bits for subpriority
373    *           @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
374    *                                      0 bits for subpriority
375    * @param  pPreemptPriority Pointer on the Preemptive priority value (starting from 0).
376    * @param  pSubPriority Pointer on the Subpriority value (starting from 0).
377    * @retval None
378    */
379  void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
380  {
381    /* Check the parameters */
382    assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
383   /* Get priority for Cortex-M system or device specific interrupts */
384    NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
385  }
386  
387  /**
388    * @brief  Sets Pending bit of an external interrupt.
389    * @param  IRQn External interrupt number
390    *         This parameter can be an enumerator of IRQn_Type enumeration
391    *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
392    * @retval None
393    */
394  void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
395  {
396    /* Check the parameters */
397    assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
398    
399    /* Set interrupt pending */
400    NVIC_SetPendingIRQ(IRQn);
401  }
402  
403  /**
404    * @brief  Gets Pending Interrupt (reads the pending register in the NVIC 
405    *         and returns the pending bit for the specified interrupt).
406    * @param  IRQn External interrupt number.
407    *          This parameter can be an enumerator of IRQn_Type enumeration
408    *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
409    * @retval status: - 0  Interrupt status is not pending.
410    *                 - 1  Interrupt status is pending.
411    */
412  uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
413  {
414    /* Check the parameters */
415    assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
416    
417    /* Return 1 if pending else 0 */
418    return NVIC_GetPendingIRQ(IRQn);
419  }
420  
421  /**
422    * @brief  Clears the pending bit of an external interrupt.
423    * @param  IRQn External interrupt number.
424    *         This parameter can be an enumerator of IRQn_Type enumeration
425    *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
426    * @retval None
427    */
428  void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
429  {
430    /* Check the parameters */
431    assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
432    
433    /* Clear pending interrupt */
434    NVIC_ClearPendingIRQ(IRQn);
435  }
436  
437  /**
438    * @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
439    * @param IRQn External interrupt number
440    *         This parameter can be an enumerator of IRQn_Type enumeration
441    *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
442    * @retval status: - 0  Interrupt status is not pending.
443    *                 - 1  Interrupt status is pending.
444    */
445  uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
446  {
447    /* Check the parameters */
448    assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
449    
450    /* Return 1 if active else 0 */
451    return NVIC_GetActive(IRQn);
452  }
453  
454  /**
455    * @brief  Configures the SysTick clock source.
456    * @param  CLKSource specifies the SysTick clock source.
457    *          This parameter can be one of the following values:
458    *             @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
459    *             @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
460    * @retval None
461    */
462  void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
463  {
464    /* Check the parameters */
465    assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
466    if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
467    {
468      SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
469    }
470    else
471    {
472      SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
473    }
474  }
475  
476  /**
477    * @brief  This function handles SYSTICK interrupt request.
478    * @retval None
479    */
480  void HAL_SYSTICK_IRQHandler(void)
481  {
482    HAL_SYSTICK_Callback();
483  }
484  
485  /**
486    * @brief  SYSTICK callback.
487    * @retval None
488    */
489  __weak void HAL_SYSTICK_Callback(void)
490  {
491    /* NOTE : This function Should not be modified, when the callback is needed,
492              the HAL_SYSTICK_Callback could be implemented in the user file
493     */
494  }
495  
496  /**
497    * @}
498    */
499  
500  /**
501    * @}
502    */
503  
504  #endif /* HAL_CORTEX_MODULE_ENABLED */
505  /**
506    * @}
507    */
508  
509  /**
510    * @}
511    */
512