Subversion Repositories AFRtranscoder

Rev

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