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