486 lines
16 KiB
C
486 lines
16 KiB
C
/*
|
|
******************************************************************************
|
|
* @file HAL_RTC.c
|
|
* @version V1.0.0
|
|
* @date 2020
|
|
* @brief RTC HAL module driver.
|
|
* This file provides firmware functions to manage the following
|
|
* functionalities of the Real-Time Clock (RTC) peripheral:
|
|
* + Initialization functions
|
|
* + Time and Date configuration
|
|
* + Alarm configuration
|
|
* + WakeUp Timer configuration
|
|
* + TimeStamp configuration
|
|
* + Tampers configuration
|
|
* + Backup Data Registers configuration
|
|
* + RTC Tamper and TimeStamp Pins Selection
|
|
* + Interrupts and flags management
|
|
******************************************************************************
|
|
*/
|
|
#include "ACM32Fxx_HAL.h"
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_Config
|
|
* Description : Initialize the RTC peripheral
|
|
* Input :
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020年
|
|
**********************************************************************************/
|
|
HAL_StatusTypeDef HAL_RTC_Config(RTC_ConfigTypeDef *hrtc)
|
|
{
|
|
#if (USE_FULL_ASSERT == 1)
|
|
/* Check RTC Parameter */
|
|
if (!IS_RTC_CLOCKSRC(hrtc->u32_ClockSource)) return HAL_ERROR;
|
|
if (!IS_RTC_COMPENSATION(hrtc->u32_Compensation)) return HAL_ERROR;
|
|
#endif
|
|
|
|
/* RTC domain write enable */
|
|
SCU->STOPCFG |= (1 << 0);
|
|
|
|
PMU->CR1 |= RPMU_CR_RTCEN;
|
|
|
|
switch (hrtc->u32_ClockSource)
|
|
{
|
|
case RTC_CLOCK_RC32K:
|
|
{
|
|
PMU->ANACR |= RPMU_ANACR_RC32K_EN;
|
|
while(!(PMU->ANACR & RPMU_ANACR_RC32K_RDY));
|
|
|
|
PMU->CR1 &= ~RTC_CLOCK_XTL;
|
|
}break;
|
|
|
|
case RTC_CLOCK_XTL:
|
|
{
|
|
PMU->ANACR = (PMU->ANACR & ~RPMU_ANACR_XTLDRV) | (RPMU_ANACR_XTLDRV_1 | RPMU_ANACR_XTLDRV_0);
|
|
|
|
PMU->ANACR |= RPMU_ANACR_XTLEN;
|
|
while(!(PMU->ANACR & RPMU_ANACR_XTLRDY));
|
|
|
|
PMU->CR1 |= RTC_CLOCK_XTL;
|
|
}break;
|
|
|
|
default: break;
|
|
}
|
|
|
|
if (hrtc->u32_CompensationValue)
|
|
{
|
|
RTC->ADJUST = hrtc->u32_Compensation | hrtc->u32_CompensationValue;
|
|
}
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_SetTime
|
|
* Description : Set RTC current time.
|
|
* Input : fp_Time Pointer to Time structure.
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_SetTime(RTC_TimeTypeDef *fp_Time)
|
|
{
|
|
#if (USE_FULL_ASSERT == 1)
|
|
/* Check RTC Parameter */
|
|
if (!IS_RTC_HOUR(fp_Time->u8_Hours)) return;
|
|
if (!IS_RTC_MIN(fp_Time->u8_Minutes)) return;
|
|
if (!IS_RTC_SEC(fp_Time->u8_Seconds)) return;
|
|
#endif
|
|
|
|
/* Write-Protect Disable */
|
|
RTC->WP = 0xCA53CA53;
|
|
|
|
RTC->HOUR = fp_Time->u8_Hours;
|
|
RTC->MIN = fp_Time->u8_Minutes;
|
|
RTC->SEC = fp_Time->u8_Seconds;
|
|
|
|
/* Write-Protect Enable */
|
|
RTC->WP = 0;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_GetTime
|
|
* Description : Get RTC current time.
|
|
* Input : fp_Time Pointer to Time structure.
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_GetTime(RTC_TimeTypeDef *fp_Time)
|
|
{
|
|
fp_Time->u8_Hours = RTC->HOUR;
|
|
fp_Time->u8_Minutes = RTC->MIN;
|
|
fp_Time->u8_Seconds = RTC->SEC;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_SetDate
|
|
* Description : Set RTC current Date.
|
|
* Input : fp_Date Pointer to Date structure.
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_SetDate(RTC_DateTypeDef *fp_Date)
|
|
{
|
|
#if (USE_FULL_ASSERT == 1)
|
|
/* Check RTC Parameter */
|
|
if (!IS_RTC_YEAR(fp_Date->u8_Year)) return;
|
|
if (!IS_RTC_MONTH(fp_Date->u8_Month)) return;
|
|
if (!IS_RTC_DAY(fp_Date->u8_Date)) return;
|
|
if (!IS_RTC_WEEKDAY(fp_Date->u8_WeekDay)) return;
|
|
#endif
|
|
|
|
/* Write-Protect Disable */
|
|
RTC->WP = 0xCA53CA53;
|
|
|
|
RTC->YEAR = fp_Date->u8_Year;
|
|
RTC->MONTH = fp_Date->u8_Month;
|
|
RTC->DATE = fp_Date->u8_Date;
|
|
RTC->WEEK = fp_Date->u8_WeekDay;
|
|
|
|
/* Write-Protect Enable */
|
|
RTC->WP = 0;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_GetDate
|
|
* Description : Get RTC current Date.
|
|
* Input : fp_Date Pointer to Date structure.
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_GetDate(RTC_DateTypeDef *fp_Date)
|
|
{
|
|
fp_Date->u8_Year = RTC->YEAR;
|
|
fp_Date->u8_Month = RTC->MONTH;
|
|
fp_Date->u8_Date = RTC->DATE;
|
|
fp_Date->u8_WeekDay = RTC->WEEK;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_AlarmConfig
|
|
* Description : Alarm Config
|
|
* Input : fp_Alarm Pointer to ALarm structure.
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_AlarmConfig(RTC_AlarmTypeDef *fp_Alarm)
|
|
{
|
|
uint32_t lu32_WeekDay;
|
|
|
|
#if (USE_FULL_ASSERT == 1)
|
|
/* Check RTC Parameter */
|
|
if (!IS_RTC_ALARM_MODE(fp_Alarm->u32_AlarmMode)) return;
|
|
if (!IS_RTC_ALARM_INT(fp_Alarm->u32_AlarmInterrupt)) return;
|
|
if (!IS_RTC_ALARM_DAY_MASK(fp_Alarm->u32_DayMask)) return;
|
|
if (!IS_RTC_ALARM_HOUR_MASK(fp_Alarm->u32_HourMask)) return;
|
|
if (!IS_RTC_ALARM_MIN_MASK(fp_Alarm->u32_MinMask)) return;
|
|
|
|
if (fp_Alarm->u32_AlarmMode == RTC_ALARM_WEEK_MODE)
|
|
{
|
|
if (!IS_RTC_ALARM_WEEKDAY(fp_Alarm->u32_AlarmWeek)) return;
|
|
}
|
|
else
|
|
{
|
|
if (!IS_RTC_DAY(fp_Alarm->u32_AlarmDay)) return;
|
|
}
|
|
|
|
if (!IS_RTC_HOUR(fp_Alarm->u32_Hours)) return;
|
|
if (!IS_RTC_MIN(fp_Alarm->u32_Minutes)) return;
|
|
if (!IS_RTC_SEC(fp_Alarm->u32_Seconds)) return;
|
|
#endif
|
|
|
|
if (fp_Alarm->u32_AlarmMode == RTC_ALARM_WEEK_MODE)
|
|
{
|
|
lu32_WeekDay = fp_Alarm->u32_AlarmWeek;
|
|
}
|
|
else
|
|
{
|
|
lu32_WeekDay = fp_Alarm->u32_AlarmDay;
|
|
}
|
|
|
|
/* Coinfig Week/Day、Hour、Min、Sec */
|
|
RTC->ALM = fp_Alarm->u32_AlarmMode | lu32_WeekDay | fp_Alarm->u32_Hours << 16 | fp_Alarm->u32_Minutes << 8 | fp_Alarm->u32_Seconds;
|
|
|
|
/* Interrupt Enable */
|
|
if (RTC_ALARM_INT_ENABLE == fp_Alarm->u32_AlarmInterrupt)
|
|
{
|
|
RTC->IE |= RTC_IE_ALM;
|
|
}
|
|
|
|
RTC->CR |= (fp_Alarm->u32_DayMask) ? RTC_ALARM_DAY_MASK_ENABLE : RTC_ALARM_DAY_MASK_DISABLE;
|
|
|
|
RTC->CR |= (fp_Alarm->u32_HourMask) ? RTC_ALARM_HOUR_MASK_ENABLE : RTC_ALARM_HOUR_MASK_DISABLE;
|
|
|
|
RTC->CR |= (fp_Alarm->u32_MinMask) ? RTC_ALARM_MIN_MASK_ENABLE : RTC_ALARM_MIN_MASK_DISABLE;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_AlarmEnable
|
|
* Description : Alarm Enable
|
|
* Input :
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_AlarmEnable(void)
|
|
{
|
|
RTC->CR |= RTC_CR_ALM_EN;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_AlarmDisable
|
|
* Description : Alarm Disable
|
|
* Input :
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_AlarmDisable(void)
|
|
{
|
|
RTC->CR &= ~RTC_CR_ALM_EN;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_Tamper
|
|
* Description : Temper1 use PC13、Temper2 use PA0
|
|
* Input :
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_Tamper(enum_Temper_t fe_Temper, RTC_TemperTypeDef *fp_Temper)
|
|
{
|
|
#if (USE_FULL_ASSERT == 1)
|
|
/* Check RTC Parameter */
|
|
if (!IS_RTC_TEMP_EDGE(fp_Temper->u32_TemperEdge)) return;
|
|
if (!IS_RTC_TEMP_INT(fp_Temper->u32_InterruptEN)) return;
|
|
if (!IS_RTC_TEMP_CLEAR_BACKUP(fp_Temper->u32_ClearBackup)) return;
|
|
if (!IS_RTC_TEMP_FILTER(fp_Temper->u32_Filter)) return;
|
|
#endif
|
|
|
|
switch (fe_Temper)
|
|
{
|
|
case RTC_TEMPER_1:
|
|
{
|
|
PMU->IOCR &= ~0x40; // Configure PC13 as digital IO
|
|
PMU->IOSEL |= 0x02; // Configure PC13 as tamper function
|
|
|
|
/* Clear Config */
|
|
RTC->CR &= ~(RTC_CR_TAMP1RCLR | RTC_CR_TAMP1FCLR | RTC_CR_TAMP1FLTEN | RTC_CR_TAMP1FLT | RTC_CR_TS1EDGE | RTC_CR_TAMPFLTCLK);
|
|
/* Edge select */
|
|
RTC->CR |= fp_Temper->u32_TemperEdge ? RTC_CR_TS1EDGE : 0x00;
|
|
/* Auto clear backup register */
|
|
if (fp_Temper->u32_ClearBackup)
|
|
{
|
|
RTC->CR |= fp_Temper->u32_TemperEdge ? RTC_CR_TAMP1FCLR : RTC_CR_TAMP1RCLR;
|
|
}
|
|
/* Temper filter */
|
|
if (fp_Temper->u32_Filter)
|
|
{
|
|
if (fp_Temper->u32_Filter == RTC_TEMP_FILTER_512_RTCCLK)
|
|
{
|
|
RTC->CR |= RTC_CR_TAMPFLTCLK;
|
|
}
|
|
else
|
|
{
|
|
RTC->CR |= (fp_Temper->u32_Filter - 2) << 13;
|
|
}
|
|
}
|
|
|
|
RTC->CR |= RTC_CR_TAMP1EN;
|
|
System_Delay(2000);
|
|
RTC->SR |= (RTC_SR_STP1FIE|RTC_SR_STP1RIE);
|
|
RTC->IE &= (~(RTC_IE_STP1FIE|RTC_IE_STP1RIE));
|
|
|
|
/* Put Temper Interrupt enable here !!!*/
|
|
if (fp_Temper->u32_InterruptEN)
|
|
{
|
|
RTC->IE |= fp_Temper->u32_TemperEdge ? RTC_IE_STP1FIE : RTC_IE_STP1RIE;
|
|
}
|
|
|
|
}break;
|
|
|
|
case RTC_TEMPER_2:
|
|
{
|
|
/* Clear Config */
|
|
RTC->CR &= ~(RTC_CR_TAMP2RCLR | RTC_CR_TAMP2FCLR | RTC_CR_TAMP2FLTEN | RTC_CR_TAMP2FLT | RTC_CR_TS2EDGE | RTC_CR_TAMPFLTCLK);
|
|
/* Edge select */
|
|
RTC->CR |= fp_Temper->u32_TemperEdge ? RTC_CR_TS2EDGE : 0x00;
|
|
/* Auto clear backup register */
|
|
if (fp_Temper->u32_ClearBackup)
|
|
{
|
|
RTC->CR |= fp_Temper->u32_TemperEdge ? RTC_CR_TAMP2FCLR : RTC_CR_TAMP2RCLR;
|
|
}
|
|
/* Temper filter */
|
|
if (fp_Temper->u32_Filter)
|
|
{
|
|
if (fp_Temper->u32_Filter == RTC_TEMP_FILTER_512_RTCCLK)
|
|
{
|
|
RTC->CR |= RTC_CR_TAMPFLTCLK;
|
|
}
|
|
else
|
|
{
|
|
RTC->CR |= (fp_Temper->u32_Filter - 2) << 19;
|
|
}
|
|
}
|
|
|
|
RTC->CR |= RTC_CR_TAMP2EN;
|
|
System_Delay(2000);
|
|
RTC->SR |= (RTC_SR_STP2FIE|RTC_SR_STP2RIE);
|
|
RTC->IE &= (~(RTC_IE_STP2FIE|RTC_IE_STP2RIE));
|
|
|
|
/* Temper Interrupt */
|
|
if (fp_Temper->u32_InterruptEN)
|
|
{
|
|
RTC->IE |= fp_Temper->u32_TemperEdge ? RTC_IE_STP2FIE : RTC_IE_STP2RIE;
|
|
}
|
|
|
|
}break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_TamperEnable
|
|
* Description :
|
|
* Input :
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_TamperEnable(enum_Temper_t fe_Temper)
|
|
{
|
|
if (fe_Temper == RTC_TEMPER_1)
|
|
{
|
|
RTC->CR |= RTC_CR_TAMP1EN;
|
|
}
|
|
else
|
|
{
|
|
RTC->CR |= RTC_CR_TAMP2EN;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_TamperDisable
|
|
* Description :
|
|
* Input :
|
|
* Outpu :
|
|
* Author : Chris_Kyle Data : 2020定
|
|
**********************************************************************************/
|
|
void HAL_RTC_TamperDisable(enum_Temper_t fe_Temper)
|
|
{
|
|
if (fe_Temper == RTC_TEMPER_1)
|
|
{
|
|
RTC->CR &= ~RTC_CR_TAMP1EN;
|
|
}
|
|
else
|
|
{
|
|
RTC->CR &= ~RTC_CR_TAMP2EN;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************************************
|
|
* Function : HAL_RTC_Standby_Wakeup
|
|
* Description : wakeup source select
|
|
* Input : fu32_Edge 0: Rising edge
|
|
* 1: Falling edge
|
|
* fe_Wakeup : wakeup source select, STANDBY_WAKEUP_RISING, STANDBY_WAKEUP_FALLING
|
|
* Outpu :
|
|
* Author : Chris_Kyle Date : 2021
|
|
*******************************************************************************************************/
|
|
void HAL_RTC_Standby_Wakeup(enum_WKUP_t fe_Wakeup, uint32_t fu32_Edge)
|
|
{
|
|
switch (fe_Wakeup)
|
|
{
|
|
case RTC_WAKEUP_WKUP1:
|
|
case RTC_WAKEUP_WKUP2:
|
|
case RTC_WAKEUP_WKUP3:
|
|
case RTC_WAKEUP_WKUP4:
|
|
case RTC_WAKEUP_WKUP5:
|
|
case RTC_WAKEUP_WKUP6:
|
|
{
|
|
/* Clear flags、Standby Enable */
|
|
PMU->CR1 |= RPMU_CR_STB_EN | RPMU_CR_CWUF | RPMU_CR_CSBF;
|
|
|
|
/* Wakeup IO Filter Enable */
|
|
PMU->CR1 |= fe_Wakeup << 8;
|
|
/* Wakeup IO Enable */
|
|
PMU->CR1 |= fe_Wakeup;
|
|
|
|
if (fe_Wakeup == RTC_WAKEUP_WKUP2)
|
|
{
|
|
/* PC13 */
|
|
PMU->IOCR &= ~0x40; // must configure PC13 as digital function
|
|
}
|
|
|
|
if (fu32_Edge)
|
|
{
|
|
PMU->CR2 |= fe_Wakeup >> 16;
|
|
}
|
|
else
|
|
{
|
|
PMU->CR2 &= ~(fe_Wakeup >> 16);
|
|
}
|
|
|
|
PMU->CR1 |= RPMU_CR_CWUF; // clear wakeup flag
|
|
System_Enter_Standby_Mode();
|
|
}break;
|
|
|
|
case RTC_WAKEUP_STAMP2:
|
|
case RTC_WAKEUP_STAMP1:
|
|
case RTC_WAKEUP_32S:
|
|
case RTC_WAKEUP_SEC:
|
|
case RTC_WAKEUP_MIN:
|
|
case RTC_WAKEUP_HOUR:
|
|
case RTC_WAKEUP_DATE:
|
|
{
|
|
/* Clear flags、Standby Enable */
|
|
PMU->CR1 |= RPMU_CR_STB_EN | RPMU_CR_CWUF | RPMU_CR_CSBF;
|
|
|
|
RTC->SR |= fe_Wakeup;
|
|
RTC->IE |= fe_Wakeup;
|
|
|
|
System_Enter_Standby_Mode();
|
|
}break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_GetStandbyStatus
|
|
* Description : Check MCU have entered standby mode
|
|
* Input :
|
|
* Outpu : 0: Not Enter Standby Mode
|
|
1: Entered Standby Mode
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
bool HAL_RTC_Get_StandbyStatus(void)
|
|
{
|
|
if (PMU->SR & RPMU_SR_SBF)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_RTC_Get_StandbyWakeupSource
|
|
* Description : Get MCU Standby Wakeup Source
|
|
* Input :
|
|
* Outpu : RTC_WAKEUP_SOURCE_BORWUF
|
|
RTC_WAKEUP_SOURCE_IWDTWUF
|
|
RTC_WAKEUP_SOURCE_RSTWUF
|
|
RTC_WAKEUP_SOURCE_RTCWUF
|
|
RTC_WAKEUP_SOURCE_WKUP6
|
|
RTC_WAKEUP_SOURCE_WKUP5
|
|
RTC_WAKEUP_SOURCE_WKUP4
|
|
RTC_WAKEUP_SOURCE_WKUP3
|
|
RTC_WAKEUP_SOURCE_WKUP2
|
|
RTC_WAKEUP_SOURCE_WKUP1
|
|
* Author : Chris_Kyle Data : 2020
|
|
**********************************************************************************/
|
|
uint32_t HAL_RTC_Get_StandbyWakeupSource(void)
|
|
{
|
|
return PMU->SR;
|
|
}
|