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