STM32F479xx HAL User Manual
stm32f4xx_hal_cortex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_cortex.c
00004   * @author  MCD Application Team
00005   * @brief   CORTEX HAL module driver.
00006   *          This file provides firmware functions to manage the following 
00007   *          functionalities of the CORTEX:
00008   *           + Initialization and de-initialization functions
00009   *           + Peripheral Control functions 
00010   *
00011   @verbatim  
00012   ==============================================================================
00013                         ##### How to use this driver #####
00014   ==============================================================================
00015 
00016     [..]  
00017     *** How to configure Interrupts using CORTEX HAL driver ***
00018     ===========================================================
00019     [..]     
00020     This section provides functions allowing to configure the NVIC interrupts (IRQ).
00021     The Cortex-M4 exceptions are managed by CMSIS functions.
00022    
00023     (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
00024         function according to the following table.
00025     (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority(). 
00026     (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
00027     (#) please refer to programming manual for details in how to configure priority. 
00028       
00029      -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible. 
00030          The pending IRQ priority will be managed only by the sub priority.
00031    
00032      -@- IRQ priority order (sorted by highest to lowest priority):
00033         (+@) Lowest preemption priority
00034         (+@) Lowest sub priority
00035         (+@) Lowest hardware priority (IRQ number)
00036  
00037     [..]  
00038     *** How to configure Systick using CORTEX HAL driver ***
00039     ========================================================
00040     [..]
00041     Setup SysTick Timer for time base.
00042            
00043    (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which
00044        is a CMSIS function that:
00045         (++) Configures the SysTick Reload register with value passed as function parameter.
00046         (++) Configures the SysTick IRQ priority to the lowest value 0x0F.
00047         (++) Resets the SysTick Counter register.
00048         (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
00049         (++) Enables the SysTick Interrupt.
00050         (++) Starts the SysTick Counter.
00051     
00052    (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
00053        __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
00054        HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
00055        inside the stm32f4xx_hal_cortex.h file.
00056 
00057    (+) You can change the SysTick IRQ priority by calling the
00058        HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function 
00059        call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
00060 
00061    (+) To adjust the SysTick time base, use the following formula:
00062                             
00063        Reload Value = SysTick Counter Clock (Hz) x  Desired Time base (s)
00064        (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
00065        (++) Reload Value should not exceed 0xFFFFFF
00066    
00067   @endverbatim
00068   ******************************************************************************
00069   * @attention
00070   *
00071   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
00072   * All rights reserved.</center></h2>
00073   *
00074   * This software component is licensed by ST under BSD 3-Clause license,
00075   * the "License"; You may not use this file except in compliance with the
00076   * License. You may obtain a copy of the License at:
00077   *                        opensource.org/licenses/BSD-3-Clause
00078   *
00079   ******************************************************************************
00080   */
00081 
00082 /* Includes ------------------------------------------------------------------*/
00083 #include "stm32f4xx_hal.h"
00084 
00085 /** @addtogroup STM32F4xx_HAL_Driver
00086   * @{
00087   */
00088 
00089 /** @defgroup CORTEX CORTEX
00090   * @brief CORTEX HAL module driver
00091   * @{
00092   */
00093 
00094 #ifdef HAL_CORTEX_MODULE_ENABLED
00095 
00096 /* Private types -------------------------------------------------------------*/
00097 /* Private variables ---------------------------------------------------------*/
00098 /* Private constants ---------------------------------------------------------*/
00099 /* Private macros ------------------------------------------------------------*/
00100 /* Private functions ---------------------------------------------------------*/
00101 /* Exported functions --------------------------------------------------------*/
00102 
00103 /** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
00104   * @{
00105   */
00106 
00107 
00108 /** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
00109  *  @brief    Initialization and Configuration functions 
00110  *
00111 @verbatim    
00112   ==============================================================================
00113               ##### Initialization and de-initialization functions #####
00114   ==============================================================================
00115     [..]
00116       This section provides the CORTEX HAL driver functions allowing to configure Interrupts
00117       Systick functionalities 
00118 
00119 @endverbatim
00120   * @{
00121   */
00122 
00123 
00124 /**
00125   * @brief  Sets the priority grouping field (preemption priority and subpriority)
00126   *         using the required unlock sequence.
00127   * @param  PriorityGroup The priority grouping bits length. 
00128   *         This parameter can be one of the following values:
00129   *         @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
00130   *                                    4 bits for subpriority
00131   *         @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
00132   *                                    3 bits for subpriority
00133   *         @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
00134   *                                    2 bits for subpriority
00135   *         @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
00136   *                                    1 bits for subpriority
00137   *         @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
00138   *                                    0 bits for subpriority
00139   * @note   When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible. 
00140   *         The pending IRQ priority will be managed only by the subpriority. 
00141   * @retval None
00142   */
00143 void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
00144 {
00145   /* Check the parameters */
00146   assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
00147   
00148   /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
00149   NVIC_SetPriorityGrouping(PriorityGroup);
00150 }
00151 
00152 /**
00153   * @brief  Sets the priority of an interrupt.
00154   * @param  IRQn External interrupt number.
00155   *         This parameter can be an enumerator of IRQn_Type enumeration
00156   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
00157   * @param  PreemptPriority The preemption priority for the IRQn channel.
00158   *         This parameter can be a value between 0 and 15
00159   *         A lower priority value indicates a higher priority 
00160   * @param  SubPriority the subpriority level for the IRQ channel.
00161   *         This parameter can be a value between 0 and 15
00162   *         A lower priority value indicates a higher priority.          
00163   * @retval None
00164   */
00165 void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
00166 { 
00167   uint32_t prioritygroup = 0x00U;
00168   
00169   /* Check the parameters */
00170   assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
00171   assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
00172   
00173   prioritygroup = NVIC_GetPriorityGrouping();
00174   
00175   NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
00176 }
00177 
00178 /**
00179   * @brief  Enables a device specific interrupt in the NVIC interrupt controller.
00180   * @note   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
00181   *         function should be called before. 
00182   * @param  IRQn External interrupt number.
00183   *         This parameter can be an enumerator of IRQn_Type enumeration
00184   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
00185   * @retval None
00186   */
00187 void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
00188 {
00189   /* Check the parameters */
00190   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
00191   
00192   /* Enable interrupt */
00193   NVIC_EnableIRQ(IRQn);
00194 }
00195 
00196 /**
00197   * @brief  Disables a device specific interrupt in the NVIC interrupt controller.
00198   * @param  IRQn External interrupt number.
00199   *         This parameter can be an enumerator of IRQn_Type enumeration
00200   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
00201   * @retval None
00202   */
00203 void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
00204 {
00205   /* Check the parameters */
00206   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
00207   
00208   /* Disable interrupt */
00209   NVIC_DisableIRQ(IRQn);
00210 }
00211 
00212 /**
00213   * @brief  Initiates a system reset request to reset the MCU.
00214   * @retval None
00215   */
00216 void HAL_NVIC_SystemReset(void)
00217 {
00218   /* System Reset */
00219   NVIC_SystemReset();
00220 }
00221 
00222 /**
00223   * @brief  Initializes the System Timer and its interrupt, and starts the System Tick Timer.
00224   *         Counter is in free running mode to generate periodic interrupts.
00225   * @param  TicksNumb Specifies the ticks Number of ticks between two interrupts.
00226   * @retval status:  - 0  Function succeeded.
00227   *                  - 1  Function failed.
00228   */
00229 uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
00230 {
00231    return SysTick_Config(TicksNumb);
00232 }
00233 /**
00234   * @}
00235   */
00236 
00237 /** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
00238  *  @brief   Cortex control functions 
00239  *
00240 @verbatim   
00241   ==============================================================================
00242                       ##### Peripheral Control functions #####
00243   ==============================================================================  
00244     [..]
00245       This subsection provides a set of functions allowing to control the CORTEX
00246       (NVIC, SYSTICK, MPU) functionalities. 
00247  
00248       
00249 @endverbatim
00250   * @{
00251   */
00252 
00253 #if (__MPU_PRESENT == 1U)
00254 /**
00255   * @brief  Disables the MPU
00256   * @retval None
00257   */
00258 void HAL_MPU_Disable(void)
00259 {
00260   /* Make sure outstanding transfers are done */
00261   __DMB();
00262 
00263   /* Disable fault exceptions */
00264   SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
00265   
00266   /* Disable the MPU and clear the control register*/
00267   MPU->CTRL = 0U;
00268 }
00269 
00270 /**
00271   * @brief  Enable the MPU.
00272   * @param  MPU_Control Specifies the control mode of the MPU during hard fault, 
00273   *          NMI, FAULTMASK and privileged access to the default memory 
00274   *          This parameter can be one of the following values:
00275   *            @arg MPU_HFNMI_PRIVDEF_NONE
00276   *            @arg MPU_HARDFAULT_NMI
00277   *            @arg MPU_PRIVILEGED_DEFAULT
00278   *            @arg MPU_HFNMI_PRIVDEF
00279   * @retval None
00280   */
00281 void HAL_MPU_Enable(uint32_t MPU_Control)
00282 {
00283   /* Enable the MPU */
00284   MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
00285   
00286   /* Enable fault exceptions */
00287   SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
00288   
00289   /* Ensure MPU setting take effects */
00290   __DSB();
00291   __ISB();
00292 }
00293 
00294 /**
00295   * @brief  Initializes and configures the Region and the memory to be protected.
00296   * @param  MPU_Init Pointer to a MPU_Region_InitTypeDef structure that contains
00297   *                the initialization and configuration information.
00298   * @retval None
00299   */
00300 void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
00301 {
00302   /* Check the parameters */
00303   assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
00304   assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
00305 
00306   /* Set the Region number */
00307   MPU->RNR = MPU_Init->Number;
00308 
00309   if ((MPU_Init->Enable) != RESET)
00310   {
00311     /* Check the parameters */
00312     assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
00313     assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
00314     assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
00315     assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
00316     assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
00317     assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
00318     assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
00319     assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
00320     
00321     MPU->RBAR = MPU_Init->BaseAddress;
00322     MPU->RASR = ((uint32_t)MPU_Init->DisableExec             << MPU_RASR_XN_Pos)   |
00323                 ((uint32_t)MPU_Init->AccessPermission        << MPU_RASR_AP_Pos)   |
00324                 ((uint32_t)MPU_Init->TypeExtField            << MPU_RASR_TEX_Pos)  |
00325                 ((uint32_t)MPU_Init->IsShareable             << MPU_RASR_S_Pos)    |
00326                 ((uint32_t)MPU_Init->IsCacheable             << MPU_RASR_C_Pos)    |
00327                 ((uint32_t)MPU_Init->IsBufferable            << MPU_RASR_B_Pos)    |
00328                 ((uint32_t)MPU_Init->SubRegionDisable        << MPU_RASR_SRD_Pos)  |
00329                 ((uint32_t)MPU_Init->Size                    << MPU_RASR_SIZE_Pos) |
00330                 ((uint32_t)MPU_Init->Enable                  << MPU_RASR_ENABLE_Pos);
00331   }
00332   else
00333   {
00334     MPU->RBAR = 0x00U;
00335     MPU->RASR = 0x00U;
00336   }
00337 }
00338 #endif /* __MPU_PRESENT */
00339 
00340 /**
00341   * @brief  Gets the priority grouping field from the NVIC Interrupt Controller.
00342   * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
00343   */
00344 uint32_t HAL_NVIC_GetPriorityGrouping(void)
00345 {
00346   /* Get the PRIGROUP[10:8] field value */
00347   return NVIC_GetPriorityGrouping();
00348 }
00349 
00350 /**
00351   * @brief  Gets the priority of an interrupt.
00352   * @param  IRQn External interrupt number.
00353   *         This parameter can be an enumerator of IRQn_Type enumeration
00354   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
00355   * @param   PriorityGroup the priority grouping bits length.
00356   *         This parameter can be one of the following values:
00357   *           @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
00358   *                                      4 bits for subpriority
00359   *           @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
00360   *                                      3 bits for subpriority
00361   *           @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
00362   *                                      2 bits for subpriority
00363   *           @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
00364   *                                      1 bits for subpriority
00365   *           @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
00366   *                                      0 bits for subpriority
00367   * @param  pPreemptPriority Pointer on the Preemptive priority value (starting from 0).
00368   * @param  pSubPriority Pointer on the Subpriority value (starting from 0).
00369   * @retval None
00370   */
00371 void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
00372 {
00373   /* Check the parameters */
00374   assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
00375  /* Get priority for Cortex-M system or device specific interrupts */
00376   NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
00377 }
00378 
00379 /**
00380   * @brief  Sets Pending bit of an external interrupt.
00381   * @param  IRQn External interrupt number
00382   *         This parameter can be an enumerator of IRQn_Type enumeration
00383   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
00384   * @retval None
00385   */
00386 void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
00387 {
00388   /* Check the parameters */
00389   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
00390   
00391   /* Set interrupt pending */
00392   NVIC_SetPendingIRQ(IRQn);
00393 }
00394 
00395 /**
00396   * @brief  Gets Pending Interrupt (reads the pending register in the NVIC 
00397   *         and returns the pending bit for the specified interrupt).
00398   * @param  IRQn External interrupt number.
00399   *          This parameter can be an enumerator of IRQn_Type enumeration
00400   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
00401   * @retval status: - 0  Interrupt status is not pending.
00402   *                 - 1  Interrupt status is pending.
00403   */
00404 uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
00405 {
00406   /* Check the parameters */
00407   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
00408   
00409   /* Return 1 if pending else 0 */
00410   return NVIC_GetPendingIRQ(IRQn);
00411 }
00412 
00413 /**
00414   * @brief  Clears the pending bit of an external interrupt.
00415   * @param  IRQn External interrupt number.
00416   *         This parameter can be an enumerator of IRQn_Type enumeration
00417   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
00418   * @retval None
00419   */
00420 void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
00421 {
00422   /* Check the parameters */
00423   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
00424   
00425   /* Clear pending interrupt */
00426   NVIC_ClearPendingIRQ(IRQn);
00427 }
00428 
00429 /**
00430   * @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
00431   * @param IRQn External interrupt number
00432   *         This parameter can be an enumerator of IRQn_Type enumeration
00433   *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
00434   * @retval status: - 0  Interrupt status is not pending.
00435   *                 - 1  Interrupt status is pending.
00436   */
00437 uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
00438 {
00439   /* Check the parameters */
00440   assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
00441   
00442   /* Return 1 if active else 0 */
00443   return NVIC_GetActive(IRQn);
00444 }
00445 
00446 /**
00447   * @brief  Configures the SysTick clock source.
00448   * @param  CLKSource specifies the SysTick clock source.
00449   *          This parameter can be one of the following values:
00450   *             @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
00451   *             @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
00452   * @retval None
00453   */
00454 void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
00455 {
00456   /* Check the parameters */
00457   assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
00458   if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
00459   {
00460     SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
00461   }
00462   else
00463   {
00464     SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
00465   }
00466 }
00467 
00468 /**
00469   * @brief  This function handles SYSTICK interrupt request.
00470   * @retval None
00471   */
00472 void HAL_SYSTICK_IRQHandler(void)
00473 {
00474   HAL_SYSTICK_Callback();
00475 }
00476 
00477 /**
00478   * @brief  SYSTICK callback.
00479   * @retval None
00480   */
00481 __weak void HAL_SYSTICK_Callback(void)
00482 {
00483   /* NOTE : This function Should not be modified, when the callback is needed,
00484             the HAL_SYSTICK_Callback could be implemented in the user file
00485    */
00486 }
00487 
00488 /**
00489   * @}
00490   */
00491 
00492 /**
00493   * @}
00494   */
00495 
00496 #endif /* HAL_CORTEX_MODULE_ENABLED */
00497 /**
00498   * @}
00499   */
00500 
00501 /**
00502   * @}
00503   */
00504 
00505 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/