SLEEP.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : SLEEP.c
  3. * Author : WCH
  4. * Version : V1.2
  5. * Date : 2022/01/18
  6. * Description : Sleep configuration and its initialization
  7. *********************************************************************************
  8. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  9. * Attention: This software (modified or not) and binary are used for
  10. * microcontroller manufactured by Nanjing Qinheng Microelectronics.
  11. *******************************************************************************/
  12. /******************************************************************************/
  13. /* Header file contains */
  14. #include "HAL.h"
  15. #define US_TO_TICK(us) (uint32_t)((us) / (1000000 / ((CAB_LSIFQ / 2))))
  16. #define SLEEP_PERIOD_MIN_US 200
  17. #define SLEEP_PERIOD_MAX_TICK 0xFFD2393F
  18. #define SLEEP_PERIOD_MIN_TICK US_TO_TICK(SLEEP_PERIOD_MIN_US)
  19. #define HESREADY_TICK US_TO_TICK(WAKE_UP_MAX_TIME_US)
  20. /*******************************************************************************
  21. * @fn BLE_LowPower
  22. *
  23. * @brief 启动睡眠
  24. *
  25. * @param time - 唤醒的时间点(RTC绝对值)
  26. *
  27. * @return state.
  28. */
  29. uint32_t BLE_LowPower(uint32_t time)
  30. {
  31. #if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
  32. uint32_t current_time;
  33. uint32_t sleep_period;
  34. uint32_t wake_time;
  35. wake_time = time - HESREADY_TICK;
  36. __disable_irq();
  37. current_time = RTC_GetCounter();
  38. sleep_period = wake_time - current_time;
  39. if((sleep_period < SLEEP_PERIOD_MIN_TICK) || (sleep_period > SLEEP_PERIOD_MAX_TICK))
  40. {
  41. __enable_irq();
  42. return 2;
  43. }
  44. RTC_SetTignTime(wake_time);
  45. __enable_irq();
  46. #if(DEBUG == DEBUG_UART1) // To use other serial ports to output printing information, you need to modify this line of code
  47. while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  48. {
  49. __NOP();
  50. }
  51. #endif
  52. // LOW POWER-sleep
  53. if(!RTCTigFlag)
  54. {
  55. PWR_EnterSTOPMode_RAM_LV(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
  56. SystemInit();
  57. }
  58. else
  59. {
  60. return 3;
  61. }
  62. #endif
  63. return 0;
  64. }
  65. /*******************************************************************************
  66. * @fn HAL_SleepInit
  67. *
  68. * @brief Configure sleep Wake-up source - RTC wake up, trigger mode
  69. *
  70. * @param None.
  71. *
  72. * @return None.
  73. */
  74. void HAL_SleepInit(void)
  75. {
  76. #if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
  77. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  78. RTC_WaitForLastTask();
  79. RTC_ITConfig(RTC_IT_ALR, ENABLE);
  80. EXTI_InitTypeDef EXTI_InitStructure = {0};
  81. NVIC_InitTypeDef NVIC_InitStructure = {0};
  82. EXTI_InitStructure.EXTI_Line = EXTI_Line17;
  83. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  84. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  85. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  86. EXTI_Init(&EXTI_InitStructure);
  87. NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
  88. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  89. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  90. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  91. NVIC_Init(&NVIC_InitStructure);
  92. #endif
  93. }