1 /**
2 ******************************************************************************
3 * @file stm32l0xx_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 M0+ exceptions are managed by CMSIS functions.
21 (#) Enable and Configure the priority of the selected IRQ Channels.
22 The priority can be 0..3.
23
24 -@- Lower priority values gives higher priority.
25 -@- Priority Order:
26 (#@) Lowest priority.
27 (#@) Lowest hardware priority (IRQn position).
28
29 (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority()
30
31 (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ()
32
33 [..]
34 *** How to configure Systick using CORTEX HAL driver ***
35 ========================================================
36 [..]
37 Setup SysTick Timer for time base.
38
39 (+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which
40 is a CMSIS function that:
41 (++) Configures the SysTick Reload register with value passed as function parameter.
42 (++) Configures the SysTick IRQ priority to the lowest value (0x03).
43 (++) Resets the SysTick Counter register.
44 (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
45 (++) Enables the SysTick Interrupt.
46 (++) Starts the SysTick Counter.
47
48 (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the function
49 HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
50 HAL_SYSTICK_Config() function call. The HAL_SYSTICK_CLKSourceConfig() function is defined
51 inside the stm32l0xx_hal_cortex.c file.
52
53 (+) You can change the SysTick IRQ priority by calling the
54 HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
55 call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
56
57 (+) To adjust the SysTick time base, use the following formula:
58
59 Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
60 (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
61 (++) Reload Value should not exceed 0xFFFFFF
62
63 @endverbatim
64 ******************************************************************************
65 * @attention
66 *
67 * Copyright (c) 2016 STMicroelectronics.
68 * All rights reserved.
69 *
70 * This software is licensed under terms that can be found in the LICENSE file in
71 * the root directory of this software component.
72 * If no LICENSE file comes with this software, it is provided AS-IS.
73 *
74 ******************************************************************************
75 */
76
77 /* Includes ------------------------------------------------------------------*/
78 #include "stm32l0xx_hal.h"
79
80 /** @addtogroup STM32L0xx_HAL_Driver
81 * @{
82 */
83
84 #ifdef HAL_CORTEX_MODULE_ENABLED
85
86 /** @addtogroup CORTEX
87 * @brief CORTEX HAL module driver
88 * @{
89 */
90
91 /* Private types -------------------------------------------------------------*/
92 /* Private variables ---------------------------------------------------------*/
93 /* Private constants ---------------------------------------------------------*/
94 /* Private macros ------------------------------------------------------------*/
95 /* Private functions ---------------------------------------------------------*/
96 /* Exported functions --------------------------------------------------------*/
97
98 /** @addtogroup CORTEX_Exported_Functions
99 * @{
100 */
101
102
103 /** @addtogroup CORTEX_Exported_Functions_Group1
104 * @brief Initialization and Configuration functions
105 *
106 @verbatim
107 ==============================================================================
108 ##### Initialization and Configuration functions #####
109 ==============================================================================
110 [..]
111 This section provides the CORTEX HAL driver functions allowing to configure Interrupts
112 Systick functionalities
113
114 @endverbatim
115 * @{
116 */
117
118 /**
119 * @brief Sets the priority of an interrupt.
120 * @param IRQn External interrupt number .
121 * This parameter can be an enumerator of IRQn_Type enumeration
122 * (For the complete STM32 Devices IRQ Channels list, please refer to stm32l0xx.h file)
123 * @param PreemptPriority The pre-emption priority for the IRQn channel.
124 * This parameter can be a value between 0 and 3.
125 * A lower priority value indicates a higher priority
126 * @param SubPriority the subpriority level for the IRQ channel.
127 * with stm32l0xx devices, this parameter is a dummy value and it is ignored, because
128 * no subpriority supported in Cortex M0+ based products.
129 * @retval None
130 */
HAL_NVIC_SetPriority(IRQn_Type IRQn,uint32_t PreemptPriority,uint32_t SubPriority)131 void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
132 {
133 /* Check the parameters */
134 assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
135 NVIC_SetPriority(IRQn,PreemptPriority);
136 }
137
138 /**
139 * @brief Enable a device specific interrupt in the NVIC interrupt controller.
140 * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
141 * function should be called before.
142 * @param IRQn External interrupt number .
143 * This parameter can be an enumerator of IRQn_Type enumeration
144 * (For the complete STM32 Devices IRQ Channels list, please refer to stm32l0xx.h file)
145 * @retval None
146 */
HAL_NVIC_EnableIRQ(IRQn_Type IRQn)147 void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
148 {
149 /* Check the parameters */
150 assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
151
152 /* Enable interrupt */
153 NVIC_EnableIRQ(IRQn);
154 }
155
156 /**
157 * @brief Disable a device specific interrupt in the NVIC interrupt controller.
158 * @param IRQn External interrupt number .
159 * This parameter can be an enumerator of IRQn_Type enumeration
160 * (For the complete STM32 Devices IRQ Channels list, please refer to stm32l0xx.h file)
161 * @retval None
162 */
HAL_NVIC_DisableIRQ(IRQn_Type IRQn)163 void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
164 {
165 /* Check the parameters */
166 assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
167
168 /* Disable interrupt */
169 NVIC_DisableIRQ(IRQn);
170 }
171
172 /**
173 * @brief Initiate a system reset request to reset the MCU.
174 * @retval None
175 */
HAL_NVIC_SystemReset(void)176 void HAL_NVIC_SystemReset(void)
177 {
178 /* System Reset */
179 NVIC_SystemReset();
180 }
181
182 /**
183 * @brief Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick)
184 * Counter is in free running mode to generate periodic interrupts.
185 * @param TicksNumb Specifies the ticks Number of ticks between two interrupts.
186 * @retval status: - 0 Function succeeded.
187 * - 1 Function failed.
188 */
HAL_SYSTICK_Config(uint32_t TicksNumb)189 uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
190 {
191 return SysTick_Config(TicksNumb);
192 }
193 /**
194 * @}
195 */
196
197 /** @addtogroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
198 * @brief Cortex control functions
199 *
200 @verbatim
201 ==============================================================================
202 ##### Peripheral Control functions #####
203 ==============================================================================
204 [..]
205 This subsection provides a set of functions allowing to control the CORTEX
206 (NVIC, SYSTICK) functionalities.
207
208
209 @endverbatim
210 * @{
211 */
212
213
214 /**
215 * @brief Gets the priority of an interrupt.
216 * @param IRQn External interrupt number.
217 * This parameter can be an enumerator of IRQn_Type enumeration
218 * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32l0xxxx.h))
219 * @retval None
220 */
HAL_NVIC_GetPriority(IRQn_Type IRQn)221 uint32_t HAL_NVIC_GetPriority(IRQn_Type IRQn)
222 {
223 /* Get priority for Cortex-M system or device specific interrupts */
224 return NVIC_GetPriority(IRQn);
225 }
226
227 /**
228 * @brief Sets Pending bit of an external interrupt.
229 * @param IRQn External interrupt number
230 * This parameter can be an enumerator of IRQn_Type enumeration
231 * (For the complete STM32 Devices IRQ Channels list, please refer to stm32l0xx.h file)
232 * @retval None
233 */
HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)234 void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
235 {
236 /* Set interrupt pending */
237 NVIC_SetPendingIRQ(IRQn);
238 }
239
240 /**
241 * @brief Get Pending Interrupt (read the pending register in the NVIC
242 * and return the pending bit for the specified interrupt).
243 * @param IRQn External interrupt number .
244 * This parameter can be an enumerator of IRQn_Type enumeration
245 * (For the complete STM32 Devices IRQ Channels list, please refer to stm32l0xx.h file)
246 * @retval status: - 0 Interrupt status is not pending.
247 * - 1 Interrupt status is pending.
248 */
HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)249 uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
250 {
251 /* Return 1 if pending else 0 */
252 return NVIC_GetPendingIRQ(IRQn);
253 }
254
255 /**
256 * @brief Clear the pending bit of an external interrupt.
257 * @param IRQn External interrupt number .
258 * This parameter can be an enumerator of IRQn_Type enumeration
259 * (For the complete STM32 Devices IRQ Channels list, please refer to stm32l0xx.h file)
260 * @retval None
261 */
HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)262 void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
263 {
264 /* Clear pending interrupt */
265 NVIC_ClearPendingIRQ(IRQn);
266 }
267
268
269 /**
270 * @brief Configure the SysTick clock source.
271 * @param CLKSource specifies the SysTick clock source.
272 * This parameter can be one of the following values:
273 * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
274 * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
275 * @retval None
276 */
HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)277 void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
278 {
279 /* Check the parameters */
280 assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
281 if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
282 {
283 SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
284 }
285 else
286 {
287 SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
288 }
289 }
290
291 /**
292 * @brief Handle SYSTICK interrupt request.
293 * @retval None
294 */
HAL_SYSTICK_IRQHandler(void)295 void HAL_SYSTICK_IRQHandler(void)
296 {
297 HAL_SYSTICK_Callback();
298 }
299
300 /**
301 * @brief SYSTICK callback.
302 * @retval None
303 */
HAL_SYSTICK_Callback(void)304 __weak void HAL_SYSTICK_Callback(void)
305 {
306 /* NOTE : This function should not be modified, when the callback is needed,
307 the HAL_SYSTICK_Callback could be implemented in the user file
308 */
309 }
310
311 #if (__MPU_PRESENT == 1U)
312 /**
313 * @brief Disable the MPU.
314 * @retval None
315 */
HAL_MPU_Disable(void)316 void HAL_MPU_Disable(void)
317 {
318
319 /*Data Memory Barrier setup */
320 __DMB();
321 /* Disable the MPU */
322 MPU->CTRL = 0;
323 }
324
325 /**
326 * @brief Enable the MPU.
327 * @param MPU_Control Specifies the control mode of the MPU during hard fault,
328 * NMI, FAULTMASK and privileged access to the default memory
329 * This parameter can be one of the following values:
330 * @arg MPU_HFNMI_PRIVDEF_NONE
331 * @arg MPU_HARDFAULT_NMI
332 * @arg MPU_PRIVILEGED_DEFAULT
333 * @arg MPU_HFNMI_PRIVDEF
334 * @retval None
335 */
336
HAL_MPU_Enable(uint32_t MPU_Control)337 void HAL_MPU_Enable(uint32_t MPU_Control)
338 {
339 /* Enable the MPU */
340 MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
341 /* Data Synchronization Barrier setup */
342 __DSB();
343 /* Instruction Synchronization Barrier setup */
344 __ISB();
345
346 }
347
348 /**
349 * @brief Initialize and configure the Region and the memory to be protected.
350 * @param MPU_Init Pointer to a MPU_Region_InitTypeDef structure that contains
351 * the initialization and configuration information.
352 * @retval None
353 */
HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef * MPU_Init)354 void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
355 {
356 /* Check the parameters */
357 assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
358 assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
359
360 /* Follow ARM recommendation with Data Memory Barrier prior to MPU configuration */
361 __DMB();
362
363 /* Set the Region number */
364 MPU->RNR = MPU_Init->Number;
365
366 if ((MPU_Init->Enable) == MPU_REGION_ENABLE)
367 {
368 /* Check the parameters */
369 assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
370 assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
371 assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
372 assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
373 assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
374 assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
375 assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
376
377 /* Set the base adsress and set the 4 LSB to 0 */
378 MPU->RBAR = (MPU_Init->BaseAddress) & 0xfffffff0U;
379
380 /* Fill the field RASR */
381 MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
382 ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
383 ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
384 ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
385 ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
386 ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
387 ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
388 ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
389 }
390 else
391 {
392 MPU->RBAR = 0x00U;
393 MPU->RASR = 0x00U;
394 }
395 }
396 #endif /* __MPU_PRESENT */
397
398
399 /**
400 * @}
401 */
402
403 /**
404 * @}
405 */
406
407 /**
408 * @}
409 */
410
411 #endif /* HAL_CORTEX_MODULE_ENABLED */
412 /**
413 * @}
414 */
415
416
417