Subversion Repositories dashGPS

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f1xx_hal_timebase_rtc_alarm_template.c
  4.   * @author  MCD Application Team
  5.   * @brief   HAL time base based on the hardware RTC_ALARM.
  6.   *
  7.   *          This file override the native HAL time base functions (defined as weak)
  8.   *          to use the RTC ALARM for time base generation:
  9.   *           + Intializes the RTC peripheral to increment the seconds registers each 1ms
  10.   *           + The alarm is configured to assert an interrupt when the RTC reaches 1ms
  11.   *           + HAL_IncTick is called at each Alarm event and the time is reset to 00:00:00
  12.   *           + HSE (default), LSE or LSI can be selected as RTC clock source
  13.  @verbatim
  14.   ==============================================================================
  15.                         ##### How to use this driver #####
  16.   ==============================================================================
  17.     [..]
  18.     This file must be copied to the application folder and modified as follows:
  19.     (#) Rename it to 'stm32f1xx_hal_timebase_rtc_alarm.c'
  20.     (#) Add this file and the RTC HAL drivers to your project and uncomment
  21.        HAL_RTC_MODULE_ENABLED define in stm32f1xx_hal_conf.h
  22.  
  23.     [..]
  24.     (@) HAL RTC alarm and HAL RTC wakeup drivers can’t be used with low power modes:
  25.         The wake up capability of the RTC may be intrusive in case of prior low power mode
  26.         configuration requiring different wake up sources.
  27.         Application/Example behavior is no more guaranteed
  28.     (@) The stm32f1xx_hal_timebase_tim use is recommended for the Applications/Examples
  29.           requiring low power modes
  30.  
  31.   @endverbatim
  32.   ******************************************************************************
  33.   * @attention
  34.   *
  35.   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  36.   * All rights reserved.</center></h2>
  37.   *
  38.   * This software component is licensed by ST under BSD 3-Clause license,
  39.   * the "License"; You may not use this file except in compliance with the
  40.   * License. You may obtain a copy of the License at:
  41.   *                        opensource.org/licenses/BSD-3-Clause
  42.   *
  43.   ******************************************************************************
  44.   */
  45.  
  46. /* Includes ------------------------------------------------------------------*/
  47. #include "stm32f1xx_hal.h"
  48. /** @addtogroup STM32F1xx_HAL_Driver
  49.   * @{
  50.   */
  51.  
  52. /** @defgroup HAL_TimeBase_RTC_Alarm_Template  HAL TimeBase RTC Alarm Template
  53.   * @{
  54.   */
  55.  
  56. /* Private typedef -----------------------------------------------------------*/
  57. /* Private define ------------------------------------------------------------*/
  58.  
  59. /* Uncomment the line below to select the appropriate RTC Clock source for your application:
  60.   + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision.
  61.   + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing
  62.                           precision.
  63.   + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing
  64.                           precision.
  65.   */
  66. #define RTC_CLOCK_SOURCE_HSE
  67. /* #define RTC_CLOCK_SOURCE_LSE */
  68. /* #define RTC_CLOCK_SOURCE_LSI */
  69.  
  70. /* Private macro -------------------------------------------------------------*/
  71. /* Private variables ---------------------------------------------------------*/
  72. RTC_HandleTypeDef        hRTC_Handle;
  73. /* Private function prototypes -----------------------------------------------*/
  74. void RTC_Alarm_IRQHandler(void);
  75. /* Private functions ---------------------------------------------------------*/
  76.  
  77. /**
  78.   * @brief  This function configures the RTC_ALARMA as a time base source.
  79.   *         The time source is configured  to have 1ms time base with a dedicated
  80.   *         Tick interrupt priority.
  81.   * @note   This function is called  automatically at the beginning of program after
  82.   *         reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
  83.   * @param  TickPriority Tick interrupt priority.
  84.   * @retval HAL status
  85.   */
  86. HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
  87. {
  88.   __IO uint32_t counter = 0U;
  89.  
  90.   RCC_OscInitTypeDef        RCC_OscInitStruct;
  91.   RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;
  92.  
  93. #ifdef RTC_CLOCK_SOURCE_LSE
  94.   /* Configue LSE as RTC clock soucre */
  95.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
  96.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  97.   RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  98.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  99. #elif defined (RTC_CLOCK_SOURCE_LSI)
  100.   /* Configue LSI as RTC clock soucre */
  101.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
  102.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  103.   RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  104.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  105. #elif defined (RTC_CLOCK_SOURCE_HSE)
  106.   /* Configue HSE as RTC clock soucre */
  107.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  108.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  109.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  110.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV128;
  111. #else
  112. #error Please select the RTC Clock source
  113. #endif /* RTC_CLOCK_SOURCE_LSE */
  114.  
  115.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK)
  116.   {
  117.     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  118.     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) == HAL_OK)
  119.     {
  120.       /* Enable RTC Clock */
  121.       __HAL_RCC_RTC_ENABLE();
  122.  
  123.       hRTC_Handle.Instance = RTC;
  124.       /* Configure RTC time base to 10Khz */
  125.       hRTC_Handle.Init.AsynchPrediv = (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC) / 10000) - 1;
  126.       hRTC_Handle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
  127.       HAL_RTC_Init(&hRTC_Handle);
  128.  
  129.       /* Disable the write protection for RTC registers */
  130.       __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
  131.  
  132.       /* Clear flag alarm A */
  133.       __HAL_RTC_ALARM_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF);
  134.  
  135.       counter = 0U;
  136.       /* Wait till RTC ALRAF flag is set and if Time out is reached exit */
  137.       while (__HAL_RTC_ALARM_GET_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF) != RESET)
  138.       {
  139.         if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
  140.         {
  141.           return HAL_ERROR;
  142.         }
  143.       }
  144.  
  145.       /* Set RTC COUNTER MSB word */
  146.       hRTC_Handle.Instance->ALRH = 0x00U;
  147.       /* Set RTC COUNTER LSB word */
  148.       hRTC_Handle.Instance->ALRL = 0x09U;
  149.  
  150.       /* RTC Alarm Interrupt Configuration: EXTI configuration */
  151.       __HAL_RTC_ALARM_EXTI_ENABLE_IT();
  152.       __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
  153.  
  154.       /* Clear Second and overflow flags */
  155.       CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
  156.  
  157.       /* Set RTC COUNTER MSB word */
  158.       hRTC_Handle.Instance->CNTH = 0x00U;
  159.       /* Set RTC COUNTER LSB word */
  160.       hRTC_Handle.Instance->CNTL = 0x00U;
  161.  
  162.       /* Configure the Alarm interrupt */
  163.       __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
  164.  
  165.       /* Enable the write protection for RTC registers */
  166.       __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
  167.  
  168.       /* Wait till RTC is in INIT state and if Time out is reached exit */
  169.       counter = 0U;
  170.       while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
  171.       {
  172.         if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
  173.         {
  174.           return HAL_ERROR;
  175.         }
  176.       }
  177.  
  178.       HAL_NVIC_SetPriority(RTC_Alarm_IRQn, TickPriority, 0U);
  179.       HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
  180.       return HAL_OK;
  181.     }
  182.   }
  183.   return HAL_ERROR;
  184. }
  185.  
  186. /**
  187.   * @brief  Suspend Tick increment.
  188.   * @note   Disable the tick increment by disabling RTC ALARM interrupt.
  189.   * @param  None
  190.   * @retval None
  191.   */
  192. void HAL_SuspendTick(void)
  193. {
  194.   /* Disable RTC ALARM update Interrupt */
  195.   __HAL_RTC_ALARM_DISABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
  196. }
  197.  
  198. /**
  199.   * @brief  Resume Tick increment.
  200.   * @note   Enable the tick increment by Enabling RTC ALARM interrupt.
  201.   * @param  None
  202.   * @retval None
  203.   */
  204. void HAL_ResumeTick(void)
  205. {
  206.   __IO uint32_t counter = 0U;
  207.  
  208.   /* Disable the write protection for RTC registers */
  209.   __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
  210.  
  211.   /* Set RTC COUNTER MSB word */
  212.   hRTC_Handle.Instance->CNTH = 0x00U;
  213.   /* Set RTC COUNTER LSB word */
  214.   hRTC_Handle.Instance->CNTL = 0x00U;
  215.  
  216.   /* Clear Second and overflow flags */
  217.   CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW | RTC_FLAG_ALRAF));
  218.  
  219.   /* Enable RTC ALARM Update interrupt */
  220.   __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
  221.  
  222.   /* Enable the write protection for RTC registers */
  223.   __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
  224.  
  225.   /* Wait till RTC is in INIT state and if Time out is reached exit */
  226.   while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
  227.   {
  228.     if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
  229.     {
  230.       break;
  231.     }
  232.   }
  233. }
  234.  
  235. /**
  236.   * @brief  ALARM A Event Callback in non blocking mode
  237.   * @note   This function is called  when RTC_ALARM interrupt took place, inside
  238.   * RTC_ALARM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  239.   * a global variable "uwTick" used as application time base.
  240.   * @param  hrtc RTC handle
  241.   * @retval None
  242.   */
  243. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
  244. {
  245.   __IO uint32_t counter = 0U;
  246.  
  247.   HAL_IncTick();
  248.  
  249.   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
  250.  
  251.   /* Set RTC COUNTER MSB word */
  252.   WRITE_REG(hrtc->Instance->CNTH, 0x00U);
  253.   /* Set RTC COUNTER LSB word */
  254.   WRITE_REG(hrtc->Instance->CNTL, 0x00U);
  255.  
  256.   /* Clear Second and overflow flags */
  257.   CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
  258.  
  259.   /* Enable the write protection for RTC registers */
  260.   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
  261.  
  262.   /* Wait till RTC is in INIT state and if Time out is reached exit */
  263.   while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
  264.   {
  265.     if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
  266.     {
  267.       break;
  268.     }
  269.   }
  270. }
  271.  
  272. /**
  273.   * @brief  This function handles RTC ALARM interrupt request.
  274.   * @retval None
  275.   */
  276. void RTC_Alarm_IRQHandler(void)
  277. {
  278.   HAL_RTC_AlarmIRQHandler(&hRTC_Handle);
  279. }
  280.  
  281. /**
  282.   * @}
  283.   */
  284.  
  285. /**
  286.   * @}
  287.   */
  288.  
  289. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  290.