1 /**
2 ******************************************************************************
3 * @file stm32l0xx_hal.c
4 * @author MCD Application Team
5 * @brief HAL module driver.
6 * This is the common part of the HAL initialization
7 *
8 ******************************************************************************
9 * @attention
10 *
11 * Copyright (c) 2016 STMicroelectronics.
12 * All rights reserved.
13 *
14 * This software is licensed under terms that can be found in the LICENSE file
15 * in the root directory of this software component.
16 * If no LICENSE file comes with this software, it is provided AS-IS.
17 *
18 ******************************************************************************
19 @verbatim
20 ==============================================================================
21 ##### How to use this driver #####
22 ==============================================================================
23 [..]
24 The common HAL driver contains a set of generic and common APIs that can be
25 used by the PPP peripheral drivers and the user to start using the HAL.
26 [..]
27 The HAL contains two APIs categories:
28 (+) Common HAL APIs
29 (+) Services HAL APIs
30
31 @endverbatim
32 ******************************************************************************
33 */
34
35 /* Includes ------------------------------------------------------------------*/
36 #include "stm32l0xx_hal.h"
37
38 /** @addtogroup STM32L0xx_HAL_Driver
39 * @{
40 */
41
42 #ifdef HAL_MODULE_ENABLED
43
44 /** @addtogroup HAL
45 * @brief HAL module driver.
46 * @{
47 */
48
49 /** @addtogroup HAL_Exported_Constants
50 * @{
51 */
52
53 /** @defgroup HAL_Version HAL Version
54 * @{
55 */
56
57 /**
58 * @brief STM32L0xx HAL Driver version number
59 */
60 #define __STM32L0xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
61 #define __STM32L0xx_HAL_VERSION_SUB1 (0x0AU) /*!< [23:16] sub1 version */
62 #define __STM32L0xx_HAL_VERSION_SUB2 (0x06U) /*!< [15:8] sub2 version */
63 #define __STM32L0xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
64 #define __STM32L0xx_HAL_VERSION ((__STM32L0xx_HAL_VERSION_MAIN << 24U)\
65 |(__STM32L0xx_HAL_VERSION_SUB1 << 16U)\
66 |(__STM32L0xx_HAL_VERSION_SUB2 << 8U )\
67 |(__STM32L0xx_HAL_VERSION_RC))
68
69 #define IDCODE_DEVID_MASK (0x00000FFFU)
70
71 /**
72 * @}
73 */
74
75 /**
76 * @}
77 */
78
79 /* Exported variables --------------------------------------------------------*/
80 /** @addtogroup HAL_Exported_Variables
81 * @{
82 */
83 __IO uint32_t uwTick;
84 uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
85 HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
86 /**
87 * @}
88 */
89
90 /* Exported functions --------------------------------------------------------*/
91 /** @addtogroup HAL_Exported_Functions
92 * @{
93 */
94
95 /** @addtogroup HAL_Exported_Functions_Group1
96 * @brief Initialization and de-initialization functions
97 *
98 @verbatim
99 ===============================================================================
100 ##### Initialization and de-initialization functions #####
101 ===============================================================================
102 [..] This section provides functions allowing to:
103 (+) Initialize the Flash interface, the NVIC allocation and initial clock
104 configuration. It initializes the source of time base also when timeout
105 is needed and the backup domain when enabled.
106 (+) De-initialize common part of the HAL.
107 (+) Configure the time base source to have 1ms time base with a dedicated
108 Tick interrupt priority.
109 (++) SysTick timer is used by default as source of time base, but user
110 can eventually implement his proper time base source (a general purpose
111 timer for example or other time source), keeping in mind that Time base
112 duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
113 handled in milliseconds basis.
114 (++) Time base configuration function (HAL_InitTick ()) is called automatically
115 at the beginning of the program after reset by HAL_Init() or at any time
116 when clock is configured, by HAL_RCC_ClockConfig().
117 (++) Source of time base is configured to generate interrupts at regular
118 time intervals. Care must be taken if HAL_Delay() is called from a
119 peripheral ISR process, the Tick interrupt line must have higher priority
120 (numerically lower) than the peripheral interrupt. Otherwise the caller
121 ISR process will be blocked.
122 (++) functions affecting time base configurations are declared as __weak
123 to make override possible in case of other implementations in user file.
124
125 @endverbatim
126 * @{
127 */
128
129 /**
130 * @brief This function configures the Flash prefetch, Flash preread and Buffer cache,
131 * Configures time base source, NVIC and Low level hardware
132 * @note This function is called at the beginning of program after reset and before
133 * the clock configuration
134 * @note The time base configuration is based on MSI clock when exiting from Reset.
135 * Once done, time base tick start incrementing.
136 * In the default implementation,Systick is used as source of time base.
137 * the tick variable is incremented each 1ms in its ISR.
138 * @retval HAL status
139 */
HAL_Init(void)140 HAL_StatusTypeDef HAL_Init(void)
141 {
142 HAL_StatusTypeDef status = HAL_OK;
143
144 /* Configure Buffer cache, Flash prefetch, Flash preread */
145 #if (BUFFER_CACHE_DISABLE != 0)
146 __HAL_FLASH_BUFFER_CACHE_DISABLE();
147 #endif /* BUFFER_CACHE_DISABLE */
148
149 #if (PREREAD_ENABLE != 0)
150 __HAL_FLASH_PREREAD_BUFFER_ENABLE();
151 #endif /* PREREAD_ENABLE */
152
153 #if (PREFETCH_ENABLE != 0)
154 __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
155 #endif /* PREFETCH_ENABLE */
156
157 /* Use SysTick as time base source and configure 1ms tick (default clock after Reset is MSI) */
158 if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
159 {
160 status = HAL_ERROR;
161 }
162 else
163 {
164 /* Init the low level hardware */
165 HAL_MspInit();
166 }
167
168 /* Return function status */
169 return status;
170 }
171
172 /**
173 * @brief This function de-initializes common part of the HAL and stops the source
174 * of time base.
175 * @note This function is optional.
176 * @retval HAL status
177 */
HAL_DeInit(void)178 HAL_StatusTypeDef HAL_DeInit(void)
179 {
180 /* Reset of all peripherals */
181 __HAL_RCC_APB1_FORCE_RESET();
182 __HAL_RCC_APB1_RELEASE_RESET();
183
184 __HAL_RCC_APB2_FORCE_RESET();
185 __HAL_RCC_APB2_RELEASE_RESET();
186
187 __HAL_RCC_AHB_FORCE_RESET();
188 __HAL_RCC_AHB_RELEASE_RESET();
189
190 __HAL_RCC_IOP_FORCE_RESET();
191 __HAL_RCC_IOP_RELEASE_RESET();
192
193 /* De-Init the low level hardware */
194 HAL_MspDeInit();
195
196 /* Return function status */
197 return HAL_OK;
198 }
199
200 /**
201 * @brief Initializes the MSP.
202 * @retval None
203 */
HAL_MspInit(void)204 __weak void HAL_MspInit(void)
205 {
206 /* NOTE : This function should not be modified, when the callback is needed,
207 the HAL_MspInit could be implemented in the user file
208 */
209 }
210
211 /**
212 * @brief DeInitializes the MSP.
213 * @retval None
214 */
HAL_MspDeInit(void)215 __weak void HAL_MspDeInit(void)
216 {
217 /* NOTE : This function should not be modified, when the callback is needed,
218 the HAL_MspDeInit could be implemented in the user file
219 */
220 }
221
222 /**
223 * @brief This function configures the source of the time base:
224 * The time source is configured to have 1ms time base with a dedicated
225 * Tick interrupt priority.
226 * @note This function is called automatically at the beginning of program after
227 * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
228 * @note In the default implementation, SysTick timer is the source of time base.
229 * It is used to generate interrupts at regular time intervals.
230 * Care must be taken if HAL_Delay() is called from a peripheral ISR process,
231 * The SysTick interrupt must have higher priority (numerically lower)
232 * than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
233 * The function is declared as __weak to be overwritten in case of other
234 * implementation in user file.
235 * @param TickPriority Tick interrupt priority.
236 * @retval HAL status
237 */
HAL_InitTick(uint32_t TickPriority)238 __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
239 {
240 /* Configure the SysTick to have interrupt in 1ms time basis*/
241 if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
242 {
243 return HAL_ERROR;
244 }
245
246 /* Configure the SysTick IRQ priority */
247 if (TickPriority < (1UL << __NVIC_PRIO_BITS))
248 {
249 HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
250 uwTickPrio = TickPriority;
251 }
252 else
253 {
254 return HAL_ERROR;
255 }
256
257 /* Return function status */
258 return HAL_OK;
259 }
260
261 /**
262 * @}
263 */
264
265 /** @addtogroup HAL_Exported_Functions_Group2
266 * @brief HAL Control functions
267 *
268 @verbatim
269 ===============================================================================
270 ##### HAL Control functions #####
271 ===============================================================================
272 [..] This section provides functions allowing to:
273 (+) Provide a tick value in millisecond
274 (+) Provide a blocking delay in millisecond
275 (+) Suspend the time base source interrupt
276 (+) Resume the time base source interrupt
277 (+) Get the HAL API driver version
278 (+) Get the device identifier
279 (+) Get the device revision identifier
280
281 @endverbatim
282 * @{
283 */
284
285 /**
286 * @brief This function is called to increment a global variable "uwTick"
287 * used as application time base.
288 * @note In the default implementation, this variable is incremented each 1ms
289 * in SysTick ISR.
290 * @note This function is declared as __weak to be overwritten in case of other
291 * implementations in user file.
292 * @retval None
293 */
HAL_IncTick(void)294 __weak void HAL_IncTick(void)
295 {
296 uwTick += uwTickFreq;
297 }
298
299 /**
300 * @brief Provides a tick value in millisecond.
301 * @note This function is declared as __weak to be overwritten in case of other
302 * implementations in user file.
303 * @retval tick value
304 */
HAL_GetTick(void)305 __weak uint32_t HAL_GetTick(void)
306 {
307 return uwTick;
308 }
309
310 /**
311 * @brief This function returns a tick priority.
312 * @retval tick priority
313 */
HAL_GetTickPrio(void)314 uint32_t HAL_GetTickPrio(void)
315 {
316 return uwTickPrio;
317 }
318
319 /**
320 * @brief Set new tick Freq.
321 * @retval Status
322 */
HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)323 HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
324 {
325 HAL_StatusTypeDef status = HAL_OK;
326 HAL_TickFreqTypeDef prevTickFreq;
327
328 assert_param(IS_TICKFREQ(Freq));
329
330 if (uwTickFreq != Freq)
331 {
332 /* Back up uwTickFreq frequency */
333 prevTickFreq = uwTickFreq;
334
335 /* Update uwTickFreq global variable used by HAL_InitTick() */
336 uwTickFreq = Freq;
337
338 /* Apply the new tick Freq */
339 status = HAL_InitTick(uwTickPrio);
340
341 if (status != HAL_OK)
342 {
343 /* Restore previous tick frequency */
344 uwTickFreq = prevTickFreq;
345 }
346 }
347
348 return status;
349 }
350
351 /**
352 * @brief Return tick frequency.
353 * @retval Tick frequency.
354 * Value of @ref HAL_TickFreqTypeDef.
355 */
HAL_GetTickFreq(void)356 HAL_TickFreqTypeDef HAL_GetTickFreq(void)
357 {
358 return uwTickFreq;
359 }
360
361 /**
362 * @brief This function provides minimum delay (in milliseconds) based
363 * on variable incremented.
364 * @note In the default implementation , SysTick timer is the source of time base.
365 * It is used to generate interrupts at regular time intervals where uwTick
366 * is incremented.
367 * @note This function is declared as __weak to be overwritten in case of other
368 * implementations in user file.
369 * @param Delay specifies the delay time length, in milliseconds.
370 * @retval None
371 */
HAL_Delay(uint32_t Delay)372 __weak void HAL_Delay(uint32_t Delay)
373 {
374 uint32_t tickstart = HAL_GetTick();
375 uint32_t wait = Delay;
376
377 /* Add a freq to guarantee minimum wait */
378 if (wait < HAL_MAX_DELAY)
379 {
380 wait += (uint32_t)(uwTickFreq);
381 }
382
383 while((HAL_GetTick() - tickstart) < wait)
384 {
385 }
386 }
387
388 /**
389 * @brief Suspends the Tick increment.
390 * @note In the default implementation , SysTick timer is the source of time base. It is
391 * used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
392 * is called, the SysTick interrupt will be disabled and so Tick increment
393 * is suspended.
394 * @note This function is declared as __weak to be overwritten in case of other
395 * implementations in user file.
396 * @retval None
397 */
HAL_SuspendTick(void)398 __weak void HAL_SuspendTick(void)
399 {
400 /* Disable SysTick Interrupt */
401 SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
402 }
403
404 /**
405 * @brief Resumes the Tick increment.
406 * @note In the default implementation , SysTick timer is the source of time base. It is
407 * used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
408 * is called, the SysTick interrupt will be enabled and so Tick increment
409 * is resumed.
410 * @note This function is declared as __weak to be overwritten in case of other
411 * implementations in user file.
412 * @retval None
413 */
HAL_ResumeTick(void)414 __weak void HAL_ResumeTick(void)
415 {
416 /* Enable SysTick Interrupt */
417 SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
418 }
419
420 /**
421 * @brief Returns the HAL revision
422 * @retval version: 0xXYZR (8bits for each decimal, R for RC)
423 */
HAL_GetHalVersion(void)424 uint32_t HAL_GetHalVersion(void)
425 {
426 return __STM32L0xx_HAL_VERSION;
427 }
428
429 /**
430 * @brief Returns the device revision identifier.
431 * @retval Device revision identifier
432 */
HAL_GetREVID(void)433 uint32_t HAL_GetREVID(void)
434 {
435 return((DBGMCU->IDCODE) >> 16U);
436 }
437
438 /**
439 * @brief Returns the device identifier.
440 * @retval Device identifier
441 */
HAL_GetDEVID(void)442 uint32_t HAL_GetDEVID(void)
443 {
444 return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
445 }
446
447 /**
448 * @brief Returns the first word of the unique device identifier (UID based on 96 bits)
449 * @retval Device identifier
450 */
HAL_GetUIDw0(void)451 uint32_t HAL_GetUIDw0(void)
452 {
453 return(READ_REG(*((uint32_t *)UID_BASE)));
454 }
455
456 /**
457 * @brief Returns the second word of the unique device identifier (UID based on 96 bits)
458 * @retval Device identifier
459 */
HAL_GetUIDw1(void)460 uint32_t HAL_GetUIDw1(void)
461 {
462 return(READ_REG(*((uint32_t *)(UID_BASE + 0x04U))));
463 }
464
465 /**
466 * @brief Returns the third word of the unique device identifier (UID based on 96 bits)
467 * @retval Device identifier
468 */
HAL_GetUIDw2(void)469 uint32_t HAL_GetUIDw2(void)
470 {
471 return(READ_REG(*((uint32_t *)(UID_BASE + 0x14U))));
472 }
473
474 /**
475 * @}
476 */
477
478 /** @addtogroup HAL_Exported_Functions_Group2
479 * @brief HAL Debug functions
480 *
481 @verbatim
482 ===============================================================================
483 ##### HAL Debug functions #####
484 ===============================================================================
485 [..] This section provides functions allowing to:
486 (+) Enable/Disable Debug module during SLEEP mode
487 (+) Enable/Disable Debug module during STOP mode
488 (+) Enable/Disable Debug module during STANDBY mode
489
490 @endverbatim
491 * @{
492 */
493
494 /**
495 * @brief Enables the Debug Module during SLEEP mode
496 * @retval None
497 */
HAL_DBGMCU_EnableDBGSleepMode(void)498 void HAL_DBGMCU_EnableDBGSleepMode(void)
499 {
500 SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
501 }
502
503 /**
504 * @brief Disables the Debug Module during SLEEP mode
505 * @retval None
506 */
HAL_DBGMCU_DisableDBGSleepMode(void)507 void HAL_DBGMCU_DisableDBGSleepMode(void)
508 {
509 CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
510 }
511
512 /**
513 * @brief Enables the Debug Module during STOP mode
514 * @retval None
515 */
HAL_DBGMCU_EnableDBGStopMode(void)516 void HAL_DBGMCU_EnableDBGStopMode(void)
517 {
518 SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
519 }
520
521 /**
522 * @brief Disables the Debug Module during STOP mode
523 * @retval None
524 */
HAL_DBGMCU_DisableDBGStopMode(void)525 void HAL_DBGMCU_DisableDBGStopMode(void)
526 {
527 CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
528 }
529
530 /**
531 * @brief Enables the Debug Module during STANDBY mode
532 * @retval None
533 */
HAL_DBGMCU_EnableDBGStandbyMode(void)534 void HAL_DBGMCU_EnableDBGStandbyMode(void)
535 {
536 SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
537 }
538
539 /**
540 * @brief Disables the Debug Module during STANDBY mode
541 * @retval None
542 */
HAL_DBGMCU_DisableDBGStandbyMode(void)543 void HAL_DBGMCU_DisableDBGStandbyMode(void)
544 {
545 CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
546 }
547
548 /**
549 * @brief Enable low power mode behavior when the MCU is in Debug mode.
550 * @param Periph: specifies the low power mode.
551 * This parameter can be any combination of the following values:
552 * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode
553 * @arg DBGMCU_STOP: Keep debugger connection during STOP mode
554 * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode
555 * @retval None
556 */
HAL_DBGMCU_DBG_EnableLowPowerConfig(uint32_t Periph)557 void HAL_DBGMCU_DBG_EnableLowPowerConfig(uint32_t Periph)
558 {
559 /* Check the parameters */
560 assert_param(IS_DBGMCU_PERIPH(Periph));
561
562 DBGMCU->CR |= Periph;
563
564 }
565 /**
566 * @brief Disable low power mode behavior when the MCU is in Debug mode.
567 * @param Periph: specifies the low power mode.
568 * This parameter can be any combination of the following values:
569 * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode
570 * @arg DBGMCU_STOP: Keep debugger connection during STOP mode
571 * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode
572 * @retval None
573 */
HAL_DBGMCU_DBG_DisableLowPowerConfig(uint32_t Periph)574 void HAL_DBGMCU_DBG_DisableLowPowerConfig(uint32_t Periph)
575 {
576 /* Check the parameters */
577 assert_param(IS_DBGMCU_PERIPH(Periph));
578 {
579 DBGMCU->CR &= ~Periph;
580 }
581 }
582
583 /**
584 * @}
585 */
586
587 /** @addtogroup HAL_Exported_Functions_Group3
588 * @brief HAL SYSCFG configuration functions
589 *
590 @verbatim
591 ===============================================================================
592 ##### HAL SYSCFG configuration functions #####
593 ===============================================================================
594 [..] This section provides functions allowing to:
595 (+) Return the boot mode
596 (+) Select the output of internal reference voltage (VREFINT)
597 (+) Lock/Unlock the SYSCFG VREF register values
598
599 @endverbatim
600 * @{
601 */
602
603 /**
604 * @brief Returns the boot mode as configured by user.
605 * @retval The boot mode as configured by user. The returned value can be one
606 * of the following values:
607 * - 0x00000000 : Boot is configured in Main Flash memory
608 * - 0x00000100 : Boot is configured in System Flash memory
609 * - 0x00000300 : Boot is configured in Embedded SRAM memory
610 */
HAL_SYSCFG_GetBootMode(void)611 uint32_t HAL_SYSCFG_GetBootMode(void)
612 {
613 return (SYSCFG->CFGR1 & SYSCFG_CFGR1_BOOT_MODE);
614 }
615
616 /**
617 * @brief Selects the output of internal reference voltage (VREFINT).
618 * The VREFINT output can be routed to(PB0) or
619 * (PB1) or both.
620 * @param SYSCFG_Vrefint_OUTPUT: new state of the Vrefint output.
621 * This parameter can be one of the following values:
622 * @arg SYSCFG_VREFINT_OUT_NONE
623 * @arg SYSCFG_VREFINT_OUT_PB0
624 * @arg SYSCFG_VREFINT_OUT_PB1
625 * @arg SYSCFG_VREFINT_OUT_PB0_PB1
626 * @retval None
627 */
HAL_SYSCFG_VREFINT_OutputSelect(uint32_t SYSCFG_Vrefint_OUTPUT)628 void HAL_SYSCFG_VREFINT_OutputSelect(uint32_t SYSCFG_Vrefint_OUTPUT)
629 {
630 /* Check the parameters */
631 assert_param(IS_SYSCFG_VREFINT_OUT_SELECT(SYSCFG_Vrefint_OUTPUT));
632
633 /* Set the output Vrefint pin */
634 SYSCFG->CFGR3 &= ~(SYSCFG_CFGR3_VREF_OUT);
635 SYSCFG->CFGR3 |= (uint32_t)(SYSCFG_Vrefint_OUTPUT);
636 }
637
638 /**
639 * @brief Lock the SYSCFG VREF register values
640 * @retval None
641 */
HAL_SYSCFG_Enable_Lock_VREFINT(void)642 void HAL_SYSCFG_Enable_Lock_VREFINT(void)
643 {
644 /* Enable the LOCK by setting REF_LOCK bit in the CFGR3 register */
645 SET_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_REF_LOCK);
646 }
647
648 /**
649 * @brief Unlock the overall SYSCFG VREF register values
650 * @retval None
651 */
HAL_SYSCFG_Disable_Lock_VREFINT(void)652 void HAL_SYSCFG_Disable_Lock_VREFINT(void)
653 {
654 /* Disable the LOCK by setting REF_LOCK bit in the CFGR3 register */
655 CLEAR_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_REF_LOCK);
656 }
657
658 /**
659 * @}
660 */
661
662 /**
663 * @}
664 */
665
666 /**
667 * @}
668 */
669 #endif /* HAL_MODULE_ENABLED */
670 /**
671 * @}
672 */
673
674
675