stm32l4xx_hal_cortex.c 21 KB

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