diff options
author | Steven Gotthardt <gotthardt@gmail.com> | 2022-12-18 15:05:51 -0700 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2023-02-13 12:12:27 -0500 |
commit | 94cbf5ff48199f4652450fbb8de682f662a2cc5a (patch) | |
tree | 1080fbd36d8e41549906404fea3c9d26c2d5ef6b /lib/hc32f460/driver/src/hc32f460_rtc.c | |
parent | 1e7057e917c0a663a508ac9b616d77ae53d78297 (diff) | |
download | kutter-94cbf5ff48199f4652450fbb8de682f662a2cc5a.tar.gz kutter-94cbf5ff48199f4652450fbb8de682f662a2cc5a.tar.xz kutter-94cbf5ff48199f4652450fbb8de682f662a2cc5a.zip |
lib: Add hc32f460 definitions
Signed-off-by: Steven Gotthardt <gotthardt@gmail.com>
Diffstat (limited to 'lib/hc32f460/driver/src/hc32f460_rtc.c')
-rw-r--r-- | lib/hc32f460/driver/src/hc32f460_rtc.c | 974 |
1 files changed, 974 insertions, 0 deletions
diff --git a/lib/hc32f460/driver/src/hc32f460_rtc.c b/lib/hc32f460/driver/src/hc32f460_rtc.c new file mode 100644 index 00000000..45695d96 --- /dev/null +++ b/lib/hc32f460/driver/src/hc32f460_rtc.c @@ -0,0 +1,974 @@ +/*******************************************************************************
+ * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
+ *
+ * This software component is licensed by HDSC under BSD 3-Clause license
+ * (the "License"); You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ */
+/******************************************************************************/
+/** \file hc32f460_rtc.c
+ **
+ ** A detailed description is available at
+ ** @link RtcGroup Real-Time Clock description @endlink
+ **
+ ** - 2018-11-22 CDT First version for Device Driver Library of RTC.
+ **
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Include files
+ ******************************************************************************/
+#include "hc32f460_rtc.h"
+#include "hc32f460_utility.h"
+
+/**
+ *******************************************************************************
+ ** \addtogroup RtcGroup
+ ******************************************************************************/
+//@{
+
+/*******************************************************************************
+ * Local type definitions ('typedef')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local pre-processor symbols/macros ('#define')
+ ******************************************************************************/
+/*!< Parameter valid check for clock source type */
+#define IS_VALID_CLK_SOURCE_TYPE(x) \
+( (RtcClkXtal32 == (x)) || \
+ (RtcClkLrc == (x)))
+
+/*!< Parameter valid check for period interrupt condition */
+#define IS_VALID_PERIOD_INT_CONDITION(x) \
+( (RtcPeriodIntInvalid == (x)) || \
+ (RtcPeriodIntHalfSec == (x)) || \
+ (RtcPeriodIntOneSec == (x)) || \
+ (RtcPeriodIntOneMin == (x)) || \
+ (RtcPeriodIntOneHour == (x)) || \
+ (RtcPeriodIntOneDay == (x)) || \
+ (RtcPeriodIntOneMon == (x)))
+
+/*!< Parameter valid check for time format */
+#define IS_VALID_TIME_FORMAT(x) \
+( (RtcTimeFormat12Hour == (x)) || \
+ (RtcTimeFormat24Hour == (x)))
+
+/*!< Parameter valid check for compensation way */
+#define IS_VALID_COMPEN_WAY(x) \
+( (RtcOutputCompenDistributed == (x)) || \
+ (RtcOutputCompenUniform == (x)))
+
+/*!< Parameter valid check for compensation value range */
+#define IS_VALID_COMPEN_VALUE_RANGE(x) ((x) <= 0x1FFu)
+
+/*!< Parameter valid check for data format */
+#define IS_VALID_DATA_FORMAT(x) \
+( (RtcDataFormatDec == (x)) || \
+ (RtcDataFormatBcd == (x)))
+
+/*!< Parameter valid check for time second */
+#define IS_VALID_TIME_SECOND(x) ((x) <= 59u)
+
+/*!< Parameter valid check for time minute */
+#define IS_VALID_TIME_MINUTE(x) ((x) <= 59u)
+
+/*!< Parameter valid check for time hour */
+#define IS_VALID_TIME_HOUR12(x) (((x) >= 1u) && ((x) <= 12u))
+#define IS_VALID_TIME_HOUR24(x) ((x) <= 23u)
+
+/*!< Parameter valid check for date weekday */
+#define IS_VALID_DATE_WEEKDAY(x) ((x) <= 6u)
+
+/*!< Parameter valid check for date day */
+#define IS_VALID_DATE_DAY(x) (((x) >= 1u) && ((x) <= 31u))
+
+/*!< Parameter valid check for date month */
+#define IS_VALID_DATE_MONTH(x) (((x) >= 1u) && ((x) <= 12u))
+
+/*!< Parameter valid check for date year */
+#define IS_VALID_DATE_YEAR(x) ((x) <= 99u)
+
+/*!< Parameter valid check for hour12 am/pm */
+#define IS_VALID_HOUR12_AMPM(x) \
+( (RtcHour12Am == (x)) || \
+ (RtcHour12Pm == (x)))
+
+/*!< Parameter valid check for alarm weekday */
+#define IS_VALID_ALARM_WEEKDAY(x) (((x) >= 1u) && ((x) <= 0x7Fu))
+
+/*!< Parameter valid check for interrupt request type */
+#define IS_VALID_IRQ_TYPE(x) \
+( (RtcIrqPeriod == (x)) || \
+ (RtcIrqAlarm == (x)))
+
+/*!< 12 hour format am/pm status bit */
+#define RTC_HOUR12_AMPM_MASK (0x20u)
+
+/*******************************************************************************
+ * Global variable definitions (declared in header file with 'extern')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function prototypes ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local variable definitions ('static')
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Function implementation - global ('extern') and local ('static')
+ ******************************************************************************/
+/**
+ *******************************************************************************
+ ** \brief De-Initialize RTC
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorTimeout De-Initialize timeout
+ **
+ ******************************************************************************/
+en_result_t RTC_DeInit(void)
+{
+ uint8_t u8RegSta;
+ uint32_t u32Timeout, u32TimeCnt = 0u;
+ en_result_t enRet = Ok;
+
+ M4_RTC->CR0_f.RESET = 0u;
+ /* Waiting for normal count status or end of RTC software reset */
+ u32Timeout = SystemCoreClock >> 8u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR0_f.RESET;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
+
+ if (1u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ /* Initialize all RTC registers */
+ M4_RTC->CR0_f.RESET = 1u;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Initialize RTC
+ **
+ ** \param [in] pstcRtcInit Pointer to RTC init configuration
+ ** \arg See the struct #stc_rtc_init_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t RTC_Init(const stc_rtc_init_t *pstcRtcInit)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcRtcInit)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_CLK_SOURCE_TYPE(pstcRtcInit->enClkSource));
+ DDL_ASSERT(IS_VALID_PERIOD_INT_CONDITION(pstcRtcInit->enPeriodInt));
+ DDL_ASSERT(IS_VALID_TIME_FORMAT(pstcRtcInit->enTimeFormat));
+ DDL_ASSERT(IS_VALID_COMPEN_WAY(pstcRtcInit->enCompenWay));
+ DDL_ASSERT(IS_VALID_COMPEN_VALUE_RANGE(pstcRtcInit->u16CompenVal));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcRtcInit->enCompenEn));
+
+ /* Configure clock */
+ if (RtcClkLrc == pstcRtcInit->enClkSource)
+ {
+ M4_RTC->CR3_f.LRCEN = 1u;
+ }
+ M4_RTC->CR3_f.RCKSEL = pstcRtcInit->enClkSource;
+
+ /* Configure control register */
+ M4_RTC->CR1_f.PRDS = pstcRtcInit->enPeriodInt;
+ M4_RTC->CR1_f.AMPM = pstcRtcInit->enTimeFormat;
+ M4_RTC->CR1_f.ONEHZSEL = pstcRtcInit->enCompenWay;
+
+ /* Configure clock error compensation register */
+ M4_RTC->ERRCRH_f.COMP8 = ((uint32_t)pstcRtcInit->u16CompenVal >> 8u) & 0x01u;
+ M4_RTC->ERRCRL = (uint32_t)pstcRtcInit->u16CompenVal & 0x00FFu;
+ M4_RTC->ERRCRH_f.COMPEN = pstcRtcInit->enCompenEn;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enter RTC read/write mode
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorTimeout Enter mode timeout
+ **
+ ******************************************************************************/
+en_result_t RTC_EnterRwMode(void)
+{
+ uint8_t u8RegSta;
+ uint32_t u32Timeout, u32TimeCnt = 0u;
+ en_result_t enRet = Ok;
+
+ /* Mode switch when RTC is running */
+ if (0u != M4_RTC->CR1_f.START)
+ {
+ M4_RTC->CR2_f.RWREQ = 1u;
+ /* Waiting for RWEN bit set */
+ u32Timeout = SystemCoreClock >> 8u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 0u));
+
+ if (0u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Exit RTC read/write mode
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorTimeout Exit mode timeout
+ **
+ ******************************************************************************/
+en_result_t RTC_ExitRwMode(void)
+{
+ uint8_t u8RegSta;
+ uint32_t u32Timeout, u32TimeCnt = 0u;
+ en_result_t enRet = Ok;
+
+ /* Mode switch when RTC is running */
+ if (0u != M4_RTC->CR1_f.START)
+ {
+ M4_RTC->CR2_f.RWREQ = 0u;
+ /* Waiting for RWEN bit reset */
+ u32Timeout = SystemCoreClock >> 8u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
+
+ if (1u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable RTC count
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable RTC count
+ ** \arg Enable Enable RTC count
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_Cmd(en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ M4_RTC->CR1_f.START = enNewSta;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief RTC period interrupt config
+ **
+ ** \param [in] enIntType Period interrupt request type
+ ** \arg RtcPeriodIntInvalid Period interrupt invalid
+ ** \arg RtcPeriodIntHalfSec 0.5 second period interrupt
+ ** \arg RtcPeriodIntOneSec 1 second period interrupt
+ ** \arg RtcPeriodIntOneMin 1 minute period interrupt
+ ** \arg RtcPeriodIntOneHour 1 hour period interrupt
+ ** \arg RtcPeriodIntOneDay 1 day period interrupt
+ ** \arg RtcPeriodIntOneMon 1 month period interrupt
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_PeriodIntConfig(en_rtc_period_int_type_t enIntType)
+{
+ uint8_t u8RtcSta;
+ uint8_t u8IntSta;
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_PERIOD_INT_CONDITION(enIntType));
+
+ u8RtcSta = (uint8_t)M4_RTC->CR1_f.START;
+ u8IntSta = (uint8_t)M4_RTC->CR2_f.PRDIE;
+ /* Disable period interrupt when START=1 and PRDIE=1 */
+ if ((1u == u8IntSta) && (1u == u8RtcSta))
+ {
+ M4_RTC->CR2_f.PRDIE = 0u;
+ }
+ M4_RTC->CR1_f.PRDS = enIntType;
+
+ if ((1u == u8IntSta) && (1u == u8RtcSta))
+ {
+ M4_RTC->CR2_f.PRDIE = 1u;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief RTC switch to low power mode
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ ** \retval ErrorInvalidMode RTC count not start
+ ** \retval ErrorTimeout Switch timeout
+ **
+ ******************************************************************************/
+en_result_t RTC_LowPowerSwitch(void)
+{
+ uint8_t u8RegSta;
+ uint32_t u32Timeout, u32TimeCnt = 0u;
+ en_result_t enRet = ErrorInvalidMode;
+
+ /* Check RTC work status */
+ if (0u != M4_RTC->CR1_f.START)
+ {
+ M4_RTC->CR2_f.RWREQ = 1u;
+ /* Waiting for RTC RWEN bit set */
+ u32Timeout = SystemCoreClock / 100u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 0u));
+
+ if (0u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ M4_RTC->CR2_f.RWREQ = 0u;
+ /* Waiting for RTC RWEN bit reset */
+ u32TimeCnt = 0u;
+ do
+ {
+ u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
+ u32TimeCnt++;
+ } while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
+
+ if (1u == u8RegSta)
+ {
+ enRet = ErrorTimeout;
+ }
+ else
+ {
+ enRet = Ok;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set RTC 1hz output compensation value
+ **
+ ** \param [in] u16CompenVal Clock compensation value
+ ** \arg 0~0x1FF
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_SetClkCompenValue(uint16_t u16CompenVal)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_COMPEN_VALUE_RANGE(u16CompenVal));
+
+ M4_RTC->ERRCRH_f.COMP8 = ((uint32_t)u16CompenVal >> 8u) & 0x01u;
+ M4_RTC->ERRCRL = (uint32_t)u16CompenVal & 0x00FFu;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable clock compensation
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable RTC clock compensation
+ ** \arg Enable Enable RTC clock compensation
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_ClkCompenCmd(en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ M4_RTC->ERRCRH_f.COMPEN = enNewSta;
+
+ return enRet;
+}
+
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable RTC 1hz output
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable RTC 1hz output
+ ** \arg Enable Enable RTC 1hz output
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_OneHzOutputCmd(en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ M4_RTC->CR1_f.ONEHZOE = enNewSta;
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set RTC current date and time
+ **
+ ** \param [in] enFormat Date and time data format
+ ** \arg RtcDataFormatDec Decimal format
+ ** \arg RtcDataFormatBcd BCD format
+ **
+ ** \param [in] pstcRtcDateTime Pointer to RTC date and time configuration
+ ** \arg See the struct #stc_rtc_date_time_t
+ **
+ ** \param [in] enUpdateDateEn The function new state(Contain year/month/day/weekday)
+ ** \arg Disable Disable update RTC date
+ ** \arg Enable Enable update RTC date
+ **
+ ** \param [in] enUpdateTimeEn The function new state(Contain hour/minute/second)
+ ** \arg Disable Disable update RTC time
+ ** \arg Enable Enable update RTC time
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Enter or exit read/write mode failed
+ ** \retval ErrorInvalidParameter Parameter enUpdateDateEn or enUpdateTimeEn invalid
+ **
+ ******************************************************************************/
+en_result_t RTC_SetDateTime(en_rtc_data_format_t enFormat, const stc_rtc_date_time_t *pstcRtcDateTime,
+ en_functional_state_t enUpdateDateEn, en_functional_state_t enUpdateTimeEn)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enUpdateDateEn));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enUpdateTimeEn));
+
+ /* Check update status */
+ if (((Disable == enUpdateDateEn) && (Disable == enUpdateTimeEn)) || (NULL == pstcRtcDateTime))
+ {
+ enRet = ErrorInvalidParameter;
+ }
+ else
+ {
+ /* Check the date parameters */
+ if (Enable == enUpdateDateEn)
+ {
+ if (RtcDataFormatDec == enFormat)
+ {
+ DDL_ASSERT(IS_VALID_DATE_YEAR(pstcRtcDateTime->u8Year));
+ DDL_ASSERT(IS_VALID_DATE_MONTH(pstcRtcDateTime->u8Month));
+ DDL_ASSERT(IS_VALID_DATE_DAY(pstcRtcDateTime->u8Day));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_DATE_YEAR(BCD2DEC(pstcRtcDateTime->u8Year)));
+ DDL_ASSERT(IS_VALID_DATE_MONTH(BCD2DEC(pstcRtcDateTime->u8Month)));
+ DDL_ASSERT(IS_VALID_DATE_DAY(BCD2DEC(pstcRtcDateTime->u8Day)));
+ }
+ DDL_ASSERT(IS_VALID_DATE_WEEKDAY(pstcRtcDateTime->u8Weekday));
+ }
+ /* Check the time parameters */
+ if (Enable == enUpdateTimeEn)
+ {
+ if (RtcDataFormatDec == enFormat)
+ {
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR12(pstcRtcDateTime->u8Hour));
+ DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcDateTime->enAmPm));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR24(pstcRtcDateTime->u8Hour));
+ }
+ DDL_ASSERT(IS_VALID_TIME_MINUTE(pstcRtcDateTime->u8Minute));
+ DDL_ASSERT(IS_VALID_TIME_SECOND(pstcRtcDateTime->u8Second));
+ }
+ else
+ {
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR12(BCD2DEC(pstcRtcDateTime->u8Hour)));
+ DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcDateTime->enAmPm));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR24(BCD2DEC(pstcRtcDateTime->u8Hour)));
+ }
+ DDL_ASSERT(IS_VALID_TIME_MINUTE(BCD2DEC(pstcRtcDateTime->u8Minute)));
+ DDL_ASSERT(IS_VALID_TIME_SECOND(BCD2DEC(pstcRtcDateTime->u8Second)));
+ }
+ }
+
+ /* Enter read/write mode */
+ if (RTC_EnterRwMode() == ErrorTimeout)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Update date */
+ if (Enable == enUpdateDateEn)
+ {
+ if (RtcDataFormatDec == enFormat)
+ {
+ M4_RTC->YEAR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Year);
+ M4_RTC->MON = DEC2BCD((uint32_t)pstcRtcDateTime->u8Month);
+ M4_RTC->DAY = DEC2BCD((uint32_t)pstcRtcDateTime->u8Day);
+ }
+ else
+ {
+ M4_RTC->YEAR = pstcRtcDateTime->u8Year;
+ M4_RTC->MON = pstcRtcDateTime->u8Month;
+ M4_RTC->DAY = pstcRtcDateTime->u8Day;
+ }
+ M4_RTC->WEEK = pstcRtcDateTime->u8Weekday;
+ }
+ /* Update time */
+ if (Enable == enUpdateTimeEn)
+ {
+ if (RtcDataFormatDec == enFormat)
+ {
+ if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
+ (RtcHour12Pm == pstcRtcDateTime->enAmPm))
+ {
+ M4_RTC->HOUR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Hour) | RTC_HOUR12_AMPM_MASK;
+ }
+ else
+ {
+ M4_RTC->HOUR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Hour);
+ }
+ M4_RTC->MIN = DEC2BCD((uint32_t)pstcRtcDateTime->u8Minute);
+ M4_RTC->SEC = DEC2BCD((uint32_t)pstcRtcDateTime->u8Second);
+ }
+ else
+ {
+ if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
+ (RtcHour12Pm == pstcRtcDateTime->enAmPm))
+ {
+ M4_RTC->HOUR = (uint32_t)pstcRtcDateTime->u8Hour | RTC_HOUR12_AMPM_MASK;
+ }
+ else
+ {
+ M4_RTC->HOUR = (uint32_t)pstcRtcDateTime->u8Hour;
+ }
+ M4_RTC->MIN = pstcRtcDateTime->u8Minute;
+ M4_RTC->SEC = pstcRtcDateTime->u8Second;
+ }
+ }
+ /* Exit read/write mode */
+ if (RTC_ExitRwMode() == ErrorTimeout)
+ {
+ enRet = Error;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get RTC current date and time
+ **
+ ** \param [in] enFormat Date and time data format
+ ** \arg RtcDataFormatDec Decimal format
+ ** \arg RtcDataFormatBcd BCD format
+ **
+ ** \param [out] pstcRtcDateTime Pointer to RTC date and time configuration
+ ** \arg See the struct #stc_rtc_date_time_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Enter or exit read/write mode failed
+ **
+ ******************************************************************************/
+en_result_t RTC_GetDateTime(en_rtc_data_format_t enFormat, stc_rtc_date_time_t *pstcRtcDateTime)
+{
+ en_result_t enRet = Ok;
+
+ if(NULL == pstcRtcDateTime)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
+
+ /* Enter read/write mode */
+ if (RTC_EnterRwMode() == ErrorTimeout)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Get RTC date and time registers */
+ pstcRtcDateTime->u8Year = (uint8_t)(M4_RTC->YEAR);
+ pstcRtcDateTime->u8Month = (uint8_t)(M4_RTC->MON);
+ pstcRtcDateTime->u8Day = (uint8_t)(M4_RTC->DAY);
+ pstcRtcDateTime->u8Weekday = (uint8_t)(M4_RTC->WEEK);
+ pstcRtcDateTime->u8Hour = (uint8_t)(M4_RTC->HOUR);
+ pstcRtcDateTime->u8Minute = (uint8_t)(M4_RTC->MIN);
+ pstcRtcDateTime->u8Second = (uint8_t)(M4_RTC->SEC);
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ if (RTC_HOUR12_AMPM_MASK == (pstcRtcDateTime->u8Hour & RTC_HOUR12_AMPM_MASK))
+ {
+ pstcRtcDateTime->u8Hour &= (uint8_t)(~RTC_HOUR12_AMPM_MASK);
+ pstcRtcDateTime->enAmPm = RtcHour12Pm;
+ }
+ else
+ {
+ pstcRtcDateTime->enAmPm = RtcHour12Am;
+ }
+ }
+
+ /* Check decimal format*/
+ if (RtcDataFormatDec == enFormat)
+ {
+ pstcRtcDateTime->u8Year = BCD2DEC(pstcRtcDateTime->u8Year);
+ pstcRtcDateTime->u8Month = BCD2DEC(pstcRtcDateTime->u8Month);
+ pstcRtcDateTime->u8Day = BCD2DEC(pstcRtcDateTime->u8Day);
+ pstcRtcDateTime->u8Hour = BCD2DEC(pstcRtcDateTime->u8Hour);
+ pstcRtcDateTime->u8Minute = BCD2DEC(pstcRtcDateTime->u8Minute);
+ pstcRtcDateTime->u8Second = BCD2DEC(pstcRtcDateTime->u8Second);
+ }
+
+ /* exit read/write mode */
+ if (RTC_ExitRwMode() == ErrorTimeout)
+ {
+ enRet = Error;
+ }
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Set RTC alarm time
+ **
+ ** \param [in] enFormat Date and time data format
+ ** \arg RtcDataFormatDec Decimal format
+ ** \arg RtcDataFormatBcd BCD format
+ **
+ ** \param [in] pstcRtcAlarmTime Pointer to RTC alarm time configuration
+ ** \arg See the struct #stc_rtc_alarm_time_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t RTC_SetAlarmTime(en_rtc_data_format_t enFormat, const stc_rtc_alarm_time_t *pstcRtcAlarmTime)
+{
+ en_result_t enRet = Ok;
+
+ if (NULL == pstcRtcAlarmTime)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
+
+ if (RtcDataFormatDec == enFormat)
+ {
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR12(pstcRtcAlarmTime->u8Hour));
+ DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcAlarmTime->enAmPm));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR24(pstcRtcAlarmTime->u8Hour));
+ }
+ DDL_ASSERT(IS_VALID_TIME_MINUTE(pstcRtcAlarmTime->u8Minute));
+ }
+ else
+ {
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR12(BCD2DEC(pstcRtcAlarmTime->u8Hour)));
+ DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcAlarmTime->enAmPm));
+ }
+ else
+ {
+ DDL_ASSERT(IS_VALID_TIME_HOUR24(BCD2DEC(pstcRtcAlarmTime->u8Hour)));
+ }
+ DDL_ASSERT(IS_VALID_TIME_MINUTE(BCD2DEC(pstcRtcAlarmTime->u8Minute)));
+ }
+ DDL_ASSERT(IS_VALID_ALARM_WEEKDAY(pstcRtcAlarmTime->u8Weekday));
+
+ /* Configure alarm registers */
+ if (RtcDataFormatDec == enFormat)
+ {
+ if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
+ (RtcHour12Pm == pstcRtcAlarmTime->enAmPm))
+ {
+ M4_RTC->ALMHOUR = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Hour) | RTC_HOUR12_AMPM_MASK;
+ }
+ else
+ {
+ M4_RTC->ALMHOUR = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Hour);
+ }
+ M4_RTC->ALMMIN = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Minute);
+ }
+ else
+ {
+ if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
+ (RtcHour12Pm == pstcRtcAlarmTime->enAmPm))
+ {
+ M4_RTC->ALMHOUR = (uint32_t)pstcRtcAlarmTime->u8Hour | RTC_HOUR12_AMPM_MASK;
+ }
+ else
+ {
+ M4_RTC->ALMHOUR = (uint32_t)pstcRtcAlarmTime->u8Hour;
+ }
+ M4_RTC->ALMMIN = pstcRtcAlarmTime->u8Minute;
+ }
+ M4_RTC->ALMWEEK = pstcRtcAlarmTime->u8Weekday;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get RTC alarm time
+ **
+ ** \param [in] enFormat Date and time data format
+ ** \arg RtcDataFormatDec Decimal format
+ ** \arg RtcDataFormatBcd BCD format
+ **
+ ** \param [out] pstcRtcAlarmTime Pointer to RTC alarm time configuration
+ ** \arg See the struct #stc_rtc_alarm_time_t
+ **
+ ** \retval Ok Process successfully done
+ ** \retval Error Parameter error
+ **
+ ******************************************************************************/
+en_result_t RTC_GetAlarmTime(en_rtc_data_format_t enFormat, stc_rtc_alarm_time_t *pstcRtcAlarmTime)
+{
+ en_result_t enRet = Ok;
+
+ if(NULL == pstcRtcAlarmTime)
+ {
+ enRet = Error;
+ }
+ else
+ {
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
+
+ /* Get RTC date and time register */
+ pstcRtcAlarmTime->u8Weekday = (uint8_t)M4_RTC->ALMWEEK;
+ pstcRtcAlarmTime->u8Minute = (uint8_t)M4_RTC->ALMMIN;
+ pstcRtcAlarmTime->u8Hour = (uint8_t)M4_RTC->ALMHOUR;
+ if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
+ {
+ if ((pstcRtcAlarmTime->u8Hour & RTC_HOUR12_AMPM_MASK) == RTC_HOUR12_AMPM_MASK)
+ {
+ pstcRtcAlarmTime->u8Hour &= (uint8_t)(~RTC_HOUR12_AMPM_MASK);
+ pstcRtcAlarmTime->enAmPm = RtcHour12Pm;
+ }
+ else
+ {
+ pstcRtcAlarmTime->enAmPm = RtcHour12Am;
+ }
+ }
+
+ /* Check decimal format*/
+ if (RtcDataFormatDec == enFormat)
+ {
+ pstcRtcAlarmTime->u8Hour = BCD2DEC(pstcRtcAlarmTime->u8Hour);
+ pstcRtcAlarmTime->u8Minute = BCD2DEC(pstcRtcAlarmTime->u8Minute);
+ }
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable RTC alarm function
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable RTC alarm function
+ ** \arg Enable Enable RTC alarm function
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_AlarmCmd(en_functional_state_t enNewSta)
+{
+ uint8_t u8RtcSta;
+ uint8_t u8IntSta;
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ u8RtcSta = (uint8_t)M4_RTC->CR1_f.START;
+ u8IntSta = (uint8_t)M4_RTC->CR2_f.ALMIE;
+ /* Disable alarm interrupt and clear alarm flag when START=1 and ALMIE=1 */
+ if ((1u == u8IntSta) && (1u == u8RtcSta))
+ {
+ M4_RTC->CR2_f.ALMIE = 0u;
+ }
+ M4_RTC->CR2_f.ALME = enNewSta;
+
+ if ((1u == u8IntSta) && (1u == u8RtcSta))
+ {
+ M4_RTC->CR1_f.ALMFCLR = 0u;
+ M4_RTC->CR2_f.ALMIE = u8IntSta;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Enable or disable RTC interrupt request
+ **
+ ** \param [in] enIrq RTC interrupt request type
+ ** \arg RtcIrqPeriod Period count interrupt request
+ ** \arg RtcIrqAlarm Alarm interrupt request
+ **
+ ** \param [in] enNewSta The function new state
+ ** \arg Disable Disable interrupt request
+ ** \arg Enable Enable interrupt request
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_IrqCmd(en_rtc_irq_type_t enIrq, en_functional_state_t enNewSta)
+{
+ en_result_t enRet = Ok;
+
+ /* Check parameters */
+ DDL_ASSERT(IS_VALID_IRQ_TYPE(enIrq));
+ DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
+
+ /* enable/disable interrupt */
+ switch (enIrq)
+ {
+ case RtcIrqPeriod:
+ M4_RTC->CR2_f.PRDIE = enNewSta;
+ break;
+ case RtcIrqAlarm:
+ M4_RTC->CR2_f.ALMIE = enNewSta;
+ break;
+ default:
+ break;
+ }
+
+ return enRet;
+}
+
+/**
+ *******************************************************************************
+ ** \brief Get RTC Alarm flag status
+ **
+ ** \param [in] None
+ **
+ ** \retval Set Flag is set
+ ** \retval Reset Flag is reset
+ **
+ ******************************************************************************/
+en_flag_status_t RTC_GetAlarmFlag(void)
+{
+ return (en_flag_status_t)(M4_RTC->CR2_f.ALMF);
+}
+
+/**
+ *******************************************************************************
+ ** \brief Clear RTC Alarm flag status
+ **
+ ** \param [in] None
+ **
+ ** \retval Ok Process successfully done
+ **
+ ******************************************************************************/
+en_result_t RTC_ClearAlarmFlag(void)
+{
+ en_result_t enRet = Ok;
+
+ M4_RTC->CR1_f.ALMFCLR = 0u;
+
+ return enRet;
+}
+
+//@} // RtcGroup
+
+/******************************************************************************
+ * EOF (not truncated)
+ *****************************************************************************/
|