/***************************************************************************//** * \file cy_rtc.c * \version 2.70 * * This file provides constants and parameter values for the APIs for the * Real-Time Clock (RTC). * ******************************************************************************** * \copyright * Copyright (c) (2016-2022), Cypress Semiconductor Corporation (an Infineon company) or * an affiliate of Cypress Semiconductor Corporation. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ #include "cy_device.h" #if defined (CY_IP_MXS40SRSS_RTC) || defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS) #include "cy_rtc.h" CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 2.2', 3, \ 'The unused code due to weak implementation can be overwritten further and then interrupt handler can call it.') #if defined(__cplusplus) extern "C" { #endif #if defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS_RTC_VERSION) && (CY_IP_MXS40SRSS_RTC_VERSION >= 3)) #define CONVERT_BCD_TO_DEC(bcdNum) (bcdNum) #define CONVERT_DEC_TO_BCD(decNum) (decNum) #else #define CONVERT_BCD_TO_DEC(bcdNum) Cy_RTC_ConvertBcdToDec(bcdNum) #define CONVERT_DEC_TO_BCD(decNum) Cy_RTC_ConvertDecToBcd(decNum) #endif /* CY_IP_MXS40SRSS_RTC, CY_IP_MXS28SRSS, CY_IP_MXS40SSRSS */ /** RTC days in months table */ uint8_t const cy_RTC_daysInMonthTbl[CY_RTC_MONTHS_PER_YEAR] = {CY_RTC_DAYS_IN_JANUARY, CY_RTC_DAYS_IN_FEBRUARY, CY_RTC_DAYS_IN_MARCH, CY_RTC_DAYS_IN_APRIL, CY_RTC_DAYS_IN_MAY, CY_RTC_DAYS_IN_JUNE, CY_RTC_DAYS_IN_JULY, CY_RTC_DAYS_IN_AUGUST, CY_RTC_DAYS_IN_SEPTEMBER, CY_RTC_DAYS_IN_OCTOBER, CY_RTC_DAYS_IN_NOVEMBER, CY_RTC_DAYS_IN_DECEMBER}; /* Static functions */ static void ConstructTimeDate(cy_stc_rtc_config_t const *timeDate, uint32_t *timeBcd, uint32_t *dateBcd); static void ConstructAlarmTimeDate(cy_stc_rtc_alarm_t const *alarmDateTime, uint32_t *alarmTimeBcd, uint32_t *alarmDateBcd); static uint32_t RelativeToFixed(cy_stc_rtc_dst_format_t const *convertDst); /******************************************************************************* * Function Name: Cy_RTC_Init ****************************************************************************//** * * Initializes the RTC driver. * * \param *config * The pointer to the RTC configuration structure, see \ref cy_stc_rtc_config_t. * * \return * Checking result. If the pointer is NULL, returns an error. * See \ref cy_en_rtc_status_t. * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_Init(cy_stc_rtc_config_t const *config) { return(Cy_RTC_SetDateAndTime(config)); } /******************************************************************************* * Function Name: Cy_RTC_SetDateAndTime ****************************************************************************//** * * Sets the time and date values into the RTC_TIME and RTC_DATE registers. * * \param dateTime * The pointer to the RTC configuration structure, see \ref cy_stc_rtc_config_t. * * \return * A validation check result of date and month. Returns an * error, if the date range is invalid. See \ref cy_en_rtc_status_t. * * \note * The function may return CY_RTC_INVALID_STATE if the RTC is * busy with previous update. In such situation, user should * call this function repetitively with appropriate parameters * to ensure that RTC is updated with provided arguments. * * \note * Refresh ALARM using \ref Cy_RTC_SetAlarmDateAndTime if it is already enabled * before calling this API. * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_SetDateAndTime(cy_stc_rtc_config_t const *dateTime) { cy_en_rtc_status_t retVal = CY_RTC_BAD_PARAM; uint32_t interruptState; uint32_t tmpTime; uint32_t tmpDate; if (NULL != dateTime) { /* Check dateTime->date input */ uint32_t tmpDaysInMonth = Cy_RTC_DaysInMonth(dateTime->month, (dateTime->year + CY_RTC_TWO_THOUSAND_YEARS)); CY_ASSERT_L3(CY_RTC_IS_SEC_VALID(dateTime->sec)); CY_ASSERT_L3(CY_RTC_IS_MIN_VALID(dateTime->min)); CY_ASSERT_L3(CY_RTC_IS_HOUR_VALID(dateTime->hour)); CY_ASSERT_L3(CY_RTC_IS_DOW_VALID(dateTime->dayOfWeek)); CY_ASSERT_L3(CY_RTC_IS_MONTH_VALID(dateTime->month)); CY_ASSERT_L3(CY_RTC_IS_YEAR_SHORT_VALID(dateTime->year)); CY_ASSERT_L3(CY_RTC_IS_DATE_VALID(dateTime->date, tmpDaysInMonth)); CY_ASSERT_L3(CY_RTC_IS_WEEK_DAY_VALID(dateTime->dayOfWeek, Cy_RTC_ConvertDayOfWeek(dateTime->date, dateTime->month, (dateTime->year + CY_RTC_TWO_THOUSAND_YEARS)))); if ((dateTime->date > 0U) && (dateTime->date <= tmpDaysInMonth)) { ConstructTimeDate(dateTime, &tmpTime, &tmpDate); /* The RTC AHB registers can be updated only under condition that the * Write bit is set and the RTC busy bit is cleared (CY_RTC_BUSY = 0). */ interruptState = Cy_SysLib_EnterCriticalSection(); retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_ENABLED); if (retVal == CY_RTC_SUCCESS) { BACKUP_RTC_TIME = tmpTime; BACKUP_RTC_DATE = tmpDate; /* Clear the RTC Write bit to finish RTC register update */ retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_DISABLED); } Cy_SysLib_ExitCriticalSection(interruptState); } } return(retVal); } /******************************************************************************* * Function Name: Cy_RTC_GetDateAndTime ****************************************************************************//** * * Gets the current RTC time and date. The AHB RTC Time and Date register values * are stored into the *dateTime structure. * * \param dateTime * The RTC time and date structure. See \ref group_rtc_data_structures. * *******************************************************************************/ void Cy_RTC_GetDateAndTime(cy_stc_rtc_config_t* dateTime) { uint32_t tmpTime; uint32_t tmpDate; CY_ASSERT_L1(NULL != dateTime); /* Read the current RTC time and date to validate the input parameters */ Cy_RTC_SyncFromRtc(); /* Write the AHB RTC registers date and time into the local variables and * updating the dateTime structure elements */ tmpTime = BACKUP_RTC_TIME; tmpDate = BACKUP_RTC_DATE; dateTime->sec = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_TIME_RTC_SEC, tmpTime)); dateTime->min = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_TIME_RTC_MIN, tmpTime)); dateTime->hrFormat = ((_FLD2BOOL(BACKUP_RTC_TIME_CTRL_12HR, tmpTime)) ? CY_RTC_12_HOURS : CY_RTC_24_HOURS); /* Read the current hour mode to know how many hour bits should be converted * In the 24-hour mode, the hour value is presented in [21:16] bits in the * BCD format. * In the 12-hour mode the hour value is presented in [20:16] bits in the BCD * format and bit [21] is present: 0 - AM; 1 - PM. */ if (dateTime->hrFormat != CY_RTC_24_HOURS) { dateTime->hour = CONVERT_BCD_TO_DEC((tmpTime & CY_RTC_BACKUP_RTC_TIME_RTC_12HOUR) >> BACKUP_RTC_TIME_RTC_HOUR_Pos); dateTime->amPm = ((0U != (tmpTime & CY_RTC_BACKUP_RTC_TIME_RTC_PM)) ? CY_RTC_PM : CY_RTC_AM); } else { dateTime->hour = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_TIME_RTC_HOUR, tmpTime)); dateTime->amPm = CY_RTC_AM; } dateTime->dayOfWeek = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_TIME_RTC_DAY, tmpTime)); dateTime->date = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_DATE_RTC_DATE, tmpDate)); dateTime->month = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_DATE_RTC_MON, tmpDate)); dateTime->year = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_DATE_RTC_YEAR, tmpDate)); } /******************************************************************************* * Function Name: Cy_RTC_SetAlarmDateAndTime ****************************************************************************//** * * Sets alarm time and date values into the ALMx_TIME and ALMx_DATE registers. * * \param alarmDateTime * The alarm configuration structure, see \ref cy_stc_rtc_alarm_t. * * \param alarmIndex * The alarm index to be configured, see \ref cy_en_rtc_alarm_t. * * \return * A validation check result of date and month. Returns an * error, if the date range is invalid. See \ref cy_en_rtc_status_t. * * \note * The function may return CY_RTC_INVALID_STATE if the RTC is * busy with previous update. In such situation, user should * call this function repetitively with appropriate parameters * to ensure that RTC is updated with provided arguments. * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_SetAlarmDateAndTime(cy_stc_rtc_alarm_t const *alarmDateTime, cy_en_rtc_alarm_t alarmIndex) { cy_en_rtc_status_t retVal = CY_RTC_BAD_PARAM; if (NULL != alarmDateTime) { uint32_t tmpYear; uint32_t interruptState; uint32_t tmpAlarmTime; uint32_t tmpAlarmDate; tmpYear = CY_RTC_TWO_THOUSAND_YEARS + CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_DATE_RTC_YEAR, BACKUP_RTC_DATE)); CY_UNUSED_PARAMETER(tmpYear); CY_ASSERT_L3(CY_RTC_IS_ALARM_IDX_VALID(alarmIndex)); CY_ASSERT_L3(CY_RTC_IS_SEC_VALID(alarmDateTime->sec)); CY_ASSERT_L3(CY_RTC_IS_ALARM_EN_VALID(alarmDateTime->secEn)); CY_ASSERT_L3(CY_RTC_IS_MIN_VALID(alarmDateTime->min)); CY_ASSERT_L3(CY_RTC_IS_ALARM_EN_VALID(alarmDateTime->minEn)); CY_ASSERT_L3(CY_RTC_IS_HOUR_VALID(alarmDateTime->hour)); CY_ASSERT_L3(CY_RTC_IS_ALARM_EN_VALID(alarmDateTime->hourEn)); CY_ASSERT_L3(CY_RTC_IS_DOW_VALID(alarmDateTime->dayOfWeek)); CY_ASSERT_L3(CY_RTC_IS_ALARM_EN_VALID(alarmDateTime->dayOfWeekEn)); CY_ASSERT_L3(CY_RTC_IS_MONTH_VALID(alarmDateTime->month)); CY_ASSERT_L3(CY_RTC_IS_ALARM_EN_VALID(alarmDateTime->monthEn)); CY_ASSERT_L3(CY_RTC_IS_ALARM_EN_VALID(alarmDateTime->dateEn)); CY_ASSERT_L3(CY_RTC_IS_ALARM_EN_VALID(alarmDateTime->almEn)); CY_ASSERT_L3(CY_RTC_IS_DATE_VALID(alarmDateTime->date, Cy_RTC_DaysInMonth(alarmDateTime->month, tmpYear))); /* Read the current RTC year to validate alarmDateTime->date */ Cy_RTC_SyncFromRtc(); ConstructAlarmTimeDate(alarmDateTime, &tmpAlarmTime, &tmpAlarmDate); /* The RTC AHB registers can be updated only under condition that the * Write bit is set and the RTC busy bit is cleared (RTC_BUSY = 0). */ interruptState = Cy_SysLib_EnterCriticalSection(); retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_ENABLED); if (CY_RTC_SUCCESS == retVal) { /* Update the AHB RTC registers with formed values */ if (alarmIndex != CY_RTC_ALARM_2) { BACKUP_ALM1_TIME = tmpAlarmTime; BACKUP_ALM1_DATE = tmpAlarmDate; } else { BACKUP_ALM2_TIME = tmpAlarmTime; BACKUP_ALM2_DATE = tmpAlarmDate; } /* Clear the RTC Write bit to finish RTC update */ retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_DISABLED); } Cy_SysLib_ExitCriticalSection(interruptState); } return(retVal); } /******************************************************************************* * Function Name: Cy_RTC_GetAlarmDateAndTime ****************************************************************************//** * * Returns the current alarm time and date values from the ALMx_TIME and * ALMx_DATE registers. * * \param alarmDateTime * The alarm configuration structure, see \ref cy_stc_rtc_alarm_t. * * \param alarmIndex * The alarm index to be configured, see \ref cy_en_rtc_alarm_t. * *******************************************************************************/ void Cy_RTC_GetAlarmDateAndTime(cy_stc_rtc_alarm_t *alarmDateTime, cy_en_rtc_alarm_t alarmIndex) { uint32_t tmpAlarmTime; uint32_t tmpAlarmDate; cy_en_rtc_hours_format_t curHoursFormat; CY_ASSERT_L1(NULL != alarmDateTime); CY_ASSERT_L3(CY_RTC_IS_ALARM_IDX_VALID(alarmIndex)); /* Read the current RTC time and date to validate the input parameters */ Cy_RTC_SyncFromRtc(); curHoursFormat = Cy_RTC_GetHoursFormat(); /* Write the AHB RTC registers into the local variables and update the * alarmDateTime structure elements */ if (alarmIndex != CY_RTC_ALARM_2) { tmpAlarmTime = BACKUP_ALM1_TIME; tmpAlarmDate = BACKUP_ALM1_DATE; alarmDateTime->sec = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM1_TIME_ALM_SEC, tmpAlarmTime)); alarmDateTime->secEn = ((_FLD2BOOL(BACKUP_ALM1_TIME_ALM_SEC_EN, tmpAlarmTime)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->min = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM1_TIME_ALM_MIN, tmpAlarmTime)); alarmDateTime->minEn = ((_FLD2BOOL(BACKUP_ALM1_TIME_ALM_MIN_EN, tmpAlarmTime)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); /* Read the current hour mode to know how many hour bits to convert. * In the 24-hour mode, the hour value is presented in [21:16] bits in * the BCD format. * In the 12-hour mode, the hour value is presented in [20:16] bits in * the BCD format and bit [21] is present: 0 - AM; 1 - PM. */ if (curHoursFormat != CY_RTC_24_HOURS) { alarmDateTime->hour = CONVERT_BCD_TO_DEC((tmpAlarmTime & CY_RTC_BACKUP_RTC_TIME_RTC_12HOUR) >> BACKUP_ALM1_TIME_ALM_HOUR_Pos); /* In the structure, the hour value should be presented in the 24-hour mode. In * that condition the firmware checks the AM/PM status and adds 12 hours to * the converted hour value if the PM bit is set. */ if ((alarmDateTime->hour < CY_RTC_HOURS_PER_HALF_DAY) && (0U != (BACKUP_ALM1_TIME & CY_RTC_BACKUP_RTC_TIME_RTC_PM))) { alarmDateTime->hour += CY_RTC_HOURS_PER_HALF_DAY; } /* Set zero hour, as the 12 A hour is zero hour in 24-hour format */ if ((alarmDateTime->hour == CY_RTC_HOURS_PER_HALF_DAY) && (0U == (BACKUP_ALM1_TIME & CY_RTC_BACKUP_RTC_TIME_RTC_PM))) { alarmDateTime->hour = 0U; } } else { alarmDateTime->hour = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM1_TIME_ALM_HOUR, tmpAlarmTime)); } alarmDateTime->hourEn = ((_FLD2BOOL(BACKUP_ALM1_TIME_ALM_HOUR_EN, tmpAlarmTime)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->dayOfWeek = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM1_TIME_ALM_DAY, tmpAlarmTime)); alarmDateTime->dayOfWeekEn = ((_FLD2BOOL(BACKUP_ALM1_TIME_ALM_DAY_EN, tmpAlarmTime)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->date = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM1_DATE_ALM_DATE, tmpAlarmDate)); alarmDateTime->dateEn = ((_FLD2BOOL(BACKUP_ALM1_DATE_ALM_DATE_EN, tmpAlarmDate)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->month = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM1_DATE_ALM_MON, tmpAlarmDate)); alarmDateTime->monthEn = ((_FLD2BOOL(BACKUP_ALM1_DATE_ALM_MON_EN, tmpAlarmDate)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->almEn = ((_FLD2BOOL(BACKUP_ALM1_DATE_ALM_EN, tmpAlarmDate)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); } else { tmpAlarmTime = BACKUP_ALM2_TIME; tmpAlarmDate = BACKUP_ALM2_DATE; alarmDateTime->sec = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM2_TIME_ALM_SEC, tmpAlarmTime)); alarmDateTime->secEn = ((_FLD2BOOL(BACKUP_ALM2_TIME_ALM_SEC_EN, tmpAlarmTime)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->min = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM2_TIME_ALM_MIN, tmpAlarmTime)); alarmDateTime->minEn = ((_FLD2BOOL(BACKUP_ALM2_TIME_ALM_MIN_EN, tmpAlarmTime)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); /* Read the current hour mode to know how many hour bits to convert. * In the 24-hour mode, the hour value is presented in [21:16] bits in * the BCD format. * In the 12-hour mode the hour value is presented in [20:16] bits in * the BCD format and bit [21] is present: 0 - AM; 1 - PM. */ if (curHoursFormat != CY_RTC_24_HOURS) { alarmDateTime->hour = CONVERT_BCD_TO_DEC((tmpAlarmTime & CY_RTC_BACKUP_RTC_TIME_RTC_12HOUR) >> BACKUP_ALM2_TIME_ALM_HOUR_Pos); /* In the structure, the hour value should be presented in the 24-hour mode. In * that condition the firmware checks the AM/PM status and adds 12 hours to * the converted hour value if the PM bit is set. */ if ((alarmDateTime->hour < CY_RTC_HOURS_PER_HALF_DAY) && (0U != (BACKUP_ALM2_TIME & CY_RTC_BACKUP_RTC_TIME_RTC_PM))) { alarmDateTime->hour += CY_RTC_HOURS_PER_HALF_DAY; } /* Set zero hour, as the 12 am hour is zero hour in 24-hour format */ else if ((alarmDateTime->hour == CY_RTC_HOURS_PER_HALF_DAY) && (0U == (BACKUP_ALM2_TIME & CY_RTC_BACKUP_RTC_TIME_RTC_PM))) { alarmDateTime->hour = 0U; } else { /* No corrections are required */ } } else { alarmDateTime->hour = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM2_TIME_ALM_HOUR, tmpAlarmTime)); } alarmDateTime->hourEn = ((_FLD2BOOL(BACKUP_ALM2_TIME_ALM_HOUR_EN, tmpAlarmTime)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->dayOfWeek = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM2_TIME_ALM_DAY, tmpAlarmTime)); alarmDateTime->dayOfWeekEn = ((_FLD2BOOL(BACKUP_ALM2_TIME_ALM_DAY_EN, tmpAlarmTime)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->date = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM2_DATE_ALM_DATE, tmpAlarmDate)); alarmDateTime->dateEn = ((_FLD2BOOL(BACKUP_ALM2_DATE_ALM_DATE_EN, tmpAlarmDate)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->month = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_ALM2_DATE_ALM_MON, tmpAlarmDate)); alarmDateTime->monthEn = ((_FLD2BOOL(BACKUP_ALM2_DATE_ALM_MON_EN, tmpAlarmDate)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); alarmDateTime->almEn = ((_FLD2BOOL(BACKUP_ALM2_DATE_ALM_EN, tmpAlarmDate)) ? CY_RTC_ALARM_ENABLE : CY_RTC_ALARM_DISABLE); } } /******************************************************************************* * Function Name: Cy_RTC_SetDateAndTimeDirect ****************************************************************************//** * * Sets the time and date values into the RTC_TIME and RTC_DATE registers using * direct time parameters. * * \param sec The second valid range is [0-59]. * * \param min The minute valid range is [0-59]. * * \param hour * The hour valid range is [0-23]. This parameter should be presented in the * 24-hour format. * * The function reads the current 12/24-hour mode, then converts the hour value * properly as the mode. * * \param date * The date valid range is [1-31], if the month of February is * selected as the Month parameter, then the valid range is [0-29]. * * \param month The month valid range is [1-12]. * * \param year The year valid range is [0-99]. * * \return * A validation check result of date and month. Returns an * error, if the date range is invalid or the RTC time and date set was * cancelled: the RTC Write bit was not set, the RTC was synchronizing. * See \ref cy_en_rtc_status_t. * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_SetDateAndTimeDirect(uint32_t sec, uint32_t min, uint32_t hour, uint32_t date, uint32_t month, uint32_t year) { cy_en_rtc_status_t retVal = CY_RTC_BAD_PARAM; cy_stc_rtc_config_t curTimeAndDate; uint32_t tmpTime; uint32_t tmpDate; uint32_t interruptState; CY_ASSERT_L3(CY_RTC_IS_SEC_VALID(sec)); CY_ASSERT_L3(CY_RTC_IS_MIN_VALID(min)); CY_ASSERT_L3(CY_RTC_IS_HOUR_VALID(hour)); CY_ASSERT_L3(CY_RTC_IS_MONTH_VALID(month)); CY_ASSERT_L3(CY_RTC_IS_YEAR_SHORT_VALID(year)); CY_ASSERT_L3(CY_RTC_IS_DATE_VALID(date, Cy_RTC_DaysInMonth(month, year + CY_RTC_TWO_THOUSAND_YEARS))); /* Fill the date and time structure */ curTimeAndDate.sec = sec; curTimeAndDate.min = min; /* Read the current hour mode */ Cy_RTC_SyncFromRtc(); if (CY_RTC_12_HOURS != Cy_RTC_GetHoursFormat()) { curTimeAndDate.hrFormat = CY_RTC_24_HOURS; curTimeAndDate.hour = hour; } else { curTimeAndDate.hrFormat = CY_RTC_12_HOURS; /* Convert the 24-hour format input value into the 12-hour format */ if (hour >= CY_RTC_HOURS_PER_HALF_DAY) { /* The current hour is more than 12 or equal 12, in the 24-hour * format. Set the PM bit and convert the hour: hour = hour - 12, * except that the hour is 12. */ curTimeAndDate.hour = (hour > CY_RTC_HOURS_PER_HALF_DAY) ? ((uint32_t) hour - CY_RTC_HOURS_PER_HALF_DAY) : hour; curTimeAndDate.amPm = CY_RTC_PM; } else { /* The current hour is less than 12 AM. The zero hour is equal * to 12:00 AM */ curTimeAndDate.hour = ((hour == 0U) ? CY_RTC_HOURS_PER_HALF_DAY : hour); curTimeAndDate.amPm = CY_RTC_AM; } } curTimeAndDate.dayOfWeek = Cy_RTC_ConvertDayOfWeek(date, month, (year + CY_RTC_TWO_THOUSAND_YEARS)); curTimeAndDate.date = date; curTimeAndDate.month = month; curTimeAndDate.year = year; ConstructTimeDate(&curTimeAndDate, &tmpTime, &tmpDate); /* The RTC AHB register can be updated only under condition that the * Write bit is set and the RTC busy bit is cleared (CY_RTC_BUSY = 0). */ interruptState = Cy_SysLib_EnterCriticalSection(); retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_ENABLED); if (retVal == CY_RTC_SUCCESS) { BACKUP_RTC_TIME = tmpTime; BACKUP_RTC_DATE = tmpDate; /* Clear the RTC Write bit to finish RTC register update */ retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_DISABLED); } Cy_SysLib_ExitCriticalSection(interruptState); return(retVal); } /******************************************************************************* * Function Name: Cy_RTC_SetAlarmDateAndTimeDirect ****************************************************************************//** * * Sets alarm time and date values into the ALMx_TIME and ALMx_DATE * registers using direct time parameters. ALM_DAY_EN is default 0 (=ignore) for * this function. * * \param sec The alarm second valid range is [0-59]. * * \param min The alarm minute valid range is [0-59]. * * \param hour * The valid range is [0-23]. * This parameter type is always in the 24-hour type. This function reads the * current 12/24-hour mode, then converts the hour value properly as the mode. * * \param date * The valid range is [1-31], if the month of February is selected as * the Month parameter, then the valid range is [0-29]. * * \param month The alarm month valid range is [1-12]. * * \param alarmIndex * The alarm index to be configured, see \ref cy_en_rtc_alarm_t. * * \return * A validation check result of date and month. Returns an * error, if the date range is invalid. See \ref cy_en_rtc_status_t. * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_SetAlarmDateAndTimeDirect(uint32_t sec, uint32_t min, uint32_t hour, uint32_t date, uint32_t month, cy_en_rtc_alarm_t alarmIndex) { uint32_t tmpCurrentYear; cy_en_rtc_status_t retVal = CY_RTC_BAD_PARAM; uint32_t tmpAlarmTime; uint32_t tmpAlarmDate; uint32_t interruptState; cy_stc_rtc_alarm_t alarmDateTime; /* Get the current year value to calculate */ tmpCurrentYear = CY_RTC_TWO_THOUSAND_YEARS + CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_DATE_RTC_YEAR, BACKUP_RTC_DATE)); CY_UNUSED_PARAMETER(tmpCurrentYear); CY_ASSERT_L3(CY_RTC_IS_SEC_VALID(sec)); CY_ASSERT_L3(CY_RTC_IS_MIN_VALID(min)); CY_ASSERT_L3(CY_RTC_IS_HOUR_VALID(hour)); CY_ASSERT_L3(CY_RTC_IS_MONTH_VALID(month)); CY_ASSERT_L3(CY_RTC_IS_ALARM_IDX_VALID(alarmIndex)); CY_ASSERT_L3(CY_RTC_IS_DATE_VALID(date, Cy_RTC_DaysInMonth(month, tmpCurrentYear))); /* Read the current time to validate the input parameters */ Cy_RTC_SyncFromRtc(); /* Fill the alarm structure */ alarmDateTime.sec = sec; alarmDateTime.secEn = CY_RTC_ALARM_ENABLE; alarmDateTime.min = min; alarmDateTime.minEn = CY_RTC_ALARM_ENABLE; alarmDateTime.hour = hour; alarmDateTime.hourEn = CY_RTC_ALARM_ENABLE; alarmDateTime.dayOfWeek = CY_RTC_SUNDAY; alarmDateTime.dayOfWeekEn = CY_RTC_ALARM_DISABLE; alarmDateTime.date = date; alarmDateTime.dateEn = CY_RTC_ALARM_ENABLE; alarmDateTime.month = month; alarmDateTime.monthEn = CY_RTC_ALARM_ENABLE; alarmDateTime.almEn = CY_RTC_ALARM_ENABLE; ConstructAlarmTimeDate(&alarmDateTime, &tmpAlarmTime, &tmpAlarmDate); /* The RTC AHB register can be updated only under condition that the * Write bit is set and the RTC busy bit is cleared (CY_RTC_BUSY = 0). */ interruptState = Cy_SysLib_EnterCriticalSection(); retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_ENABLED); if (retVal == CY_RTC_SUCCESS) { if (alarmIndex != CY_RTC_ALARM_2) { BACKUP_ALM1_TIME = tmpAlarmTime; BACKUP_ALM1_DATE = tmpAlarmDate; } else { BACKUP_ALM2_TIME = tmpAlarmTime; BACKUP_ALM2_DATE = tmpAlarmDate; } /* Clear the RTC Write bit to finish RTC register update */ retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_DISABLED); } Cy_SysLib_ExitCriticalSection(interruptState); return(retVal); } /******************************************************************************* * Function Name: Cy_RTC_SetHoursFormat ****************************************************************************//** * * Sets the 12/24-hour mode. * * \param hoursFormat * The current hour format, see \ref cy_en_rtc_hours_format_t. * * \return * A validation check result of RTC register update. See \ref cy_en_rtc_status_t. * * \note * Refresh ALARM using \ref Cy_RTC_SetAlarmDateAndTime if it is already enabled * before calling this API. * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_SetHoursFormat(cy_en_rtc_hours_format_t hoursFormat) { uint32_t curTime; cy_en_rtc_status_t retVal = CY_RTC_BAD_PARAM; CY_ASSERT_L3(CY_RTC_IS_HRS_FORMAT_VALID(hoursFormat)); /* Read the current time to validate the input parameters */ Cy_RTC_SyncFromRtc(); curTime = BACKUP_RTC_TIME; /* Hour format can be changed in condition that current hour format is not * the same as requested in function argument */ if (hoursFormat != Cy_RTC_GetHoursFormat()) { uint32_t hourValue; /* Convert the current hour value from 24H into the 12H format */ if (hoursFormat == CY_RTC_12_HOURS) { hourValue = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_TIME_RTC_HOUR, curTime)); if (hourValue >= CY_RTC_HOURS_PER_HALF_DAY) { /* The current hour is more than 12 or equal 12 in the 24-hour * mode. Set the PM bit and convert the hour: hour = hour - 12. */ hourValue = (uint32_t) (hourValue - CY_RTC_HOURS_PER_HALF_DAY); hourValue = ((0U != hourValue) ? hourValue : CY_RTC_HOURS_PER_HALF_DAY); curTime = (_CLR_SET_FLD32U(curTime, BACKUP_RTC_TIME_RTC_HOUR, CONVERT_DEC_TO_BCD(hourValue))); curTime |= CY_RTC_BACKUP_RTC_TIME_RTC_PM; } else if (hourValue < 1U) { /* The current hour in the 24-hour mode is 0 which is equal * to 12:00 AM */ curTime = (_CLR_SET_FLD32U(curTime, BACKUP_RTC_TIME_RTC_HOUR, CONVERT_DEC_TO_BCD(CY_RTC_HOURS_PER_HALF_DAY))); /* Set the AM bit */ curTime &= ((uint32_t) ~CY_RTC_BACKUP_RTC_TIME_RTC_PM); } else { /* The current hour is less than 12 */ curTime = (_CLR_SET_FLD32U(curTime, BACKUP_RTC_TIME_RTC_HOUR, CONVERT_DEC_TO_BCD(hourValue))); curTime &= ((uint32_t) ~CY_RTC_BACKUP_RTC_TIME_RTC_PM); } curTime |= BACKUP_RTC_TIME_CTRL_12HR_Msk; } /* Convert the hour value into 24H format value */ else { /* Mask the AM/PM bit as the hour value is in [20:16] bits */ hourValue = CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_TIME_RTC_HOUR, (curTime & (uint32_t) ~CY_RTC_BACKUP_RTC_TIME_RTC_PM))); /* Add 12 hours in condition that current time is in PM period */ if ((hourValue < CY_RTC_HOURS_PER_HALF_DAY) && (0U != (curTime & CY_RTC_BACKUP_RTC_TIME_RTC_PM))) { hourValue += CY_RTC_HOURS_PER_HALF_DAY; } /* Current hour is 12 AM which is equal to zero hour in 24-hour format */ if ((hourValue == CY_RTC_HOURS_PER_HALF_DAY) && (0U == (curTime & CY_RTC_BACKUP_RTC_TIME_RTC_PM))) { hourValue = 0U; } curTime = (_CLR_SET_FLD32U(curTime, BACKUP_RTC_TIME_RTC_HOUR, CONVERT_DEC_TO_BCD(hourValue))); curTime &= (uint32_t) ~BACKUP_RTC_TIME_CTRL_12HR_Msk; } /* Writing corrected hour value and hour format bit into the RTC AHB * register. The RTC AHB register can be updated only under condition * that the Write bit is set and the RTC busy bit is cleared * (CY_RTC_BUSY = 0). */ uint32_t interruptState; interruptState = Cy_SysLib_EnterCriticalSection(); retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_ENABLED); if (retVal == CY_RTC_SUCCESS) { BACKUP_RTC_TIME = curTime; /* Clear the RTC Write bit to finish RTC register update */ retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_DISABLED); } Cy_SysLib_ExitCriticalSection(interruptState); } else { retVal = CY_RTC_SUCCESS; } return(retVal); } #if defined (CY_IP_MXS40SRSS_RTC) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS) /******************************************************************************* * Function Name: Cy_RTC_SelectFrequencyPrescaler() ****************************************************************************//** * * Selects the RTC pre-scaler value and changes its clock frequency. * If the external 32.768 kHz WCO is absent on the board, the RTC can * be driven by a 32.768kHz square clock source or an external 50-Hz or 60-Hz * sine-wave clock source, for example the wall AC frequency. * * \param clkSel clock frequency, see \ref cy_en_rtc_clock_freq_t. * * In addition to generating the 32.768 kHz clock from external crystals, the WCO * can be sourced by an external clock source (50 Hz or 60Hz), even the wall AC * frequency as a timebase. The API helps select between the RTC sources: * * A 32.768 kHz digital clock source. * * An external 50-Hz or 60-Hz sine-wave clock source. * * If you want to use an external 50-Hz or 60-Hz sine-wave clock source to * drive the RTC, the next procedure is required: * -# Disable the WCO
* -# Bypass the WCO using the Cy_SysClk_WcoBypass() function. * -# Configure both wco_out and wco_in pins. Note that only one of the wco pins * should be driven and the other wco pin should be floating, which depends on * the source that drives the RTC (*1). * -# Call Cy_RTC_SelectFrequencyPrescaler(CY_RTC_FREQ_60_HZ), if you want to * drive the WCO, for example, with a 60 Hz source. * -# Enable the WCO. * * If you want to use the WCO after using an external 50-Hz or 60-Hz sine-wave * clock source: * -# Disable the WCO. * -# Switch-off the WCO bypass using the Cy_SysClk_WcoBypass() function. * -# Drive off the wco pin with an external signal source. * -# Call Cy_RTC_SelectFrequencyPrescaler(CY_RTC_FREQ_WCO_32768_HZ). * -# Enable the WCO. * * (1) - Refer to the device TRM to know how to configure the wco pins properly * and which wco pin should be driven/floating. * * \warning * There is a limitation to the external clock source frequencies. Only two * frequencies are allowed - 50 Hz or 60 Hz. Note that this limitation is related * to the RTC pre-scaling feature presented in this function. This * limitation is not related to WCO external clock sources which can drive the * WCO in Bypass mode. * * \note * This API is available for CAT1B, CAT1C and CAT1D devices. * *******************************************************************************/ void Cy_RTC_SelectFrequencyPrescaler(cy_en_rtc_clock_freq_t clkSel) { CY_ASSERT_L3(CY_RTC_IS_CLK_VALID(clkSel)); #if defined (CY_IP_MXS22SRSS) BACKUP_CTL = (_CLR_SET_FLD32U(BACKUP_CTL, SRSS_CLK_WCO_CONFIG_PRESCALER, (uint32_t) clkSel)); #else BACKUP_CTL = (_CLR_SET_FLD32U(BACKUP_CTL, BACKUP_CTL_PRESCALER, (uint32_t) clkSel)); #endif } #endif /* CY_IP_MXS40SRSS_RTC, CY_IP_MXS40SSRSS, CY_IP_MXS22SRSS*/ /******************************************************************************* * Function Name: Cy_RTC_SelectClockSource() ****************************************************************************//** * \param clkSel Source clock, see \ref cy_en_rtc_clk_select_sources_t * Selects the source clock for RTC. * * \note * This API is available for CAT1B devices. * *******************************************************************************/ void Cy_RTC_SelectClockSource(cy_en_rtc_clk_select_sources_t clkSel) { CY_ASSERT_L3(CY_RTC_IS_SRC_CLK_SELECT_VALID(clkSel)); #if defined (CY_IP_MXS22SRSS) BACKUP_CTL = (_CLR_SET_FLD32U(BACKUP_CTL, SRSS_CLK_WCO_CONFIG_CLK_RTC_SEL, (uint32_t) clkSel)); #else BACKUP_CTL = (_CLR_SET_FLD32U(BACKUP_CTL, BACKUP_CTL_CLK_SEL, (uint32_t) clkSel)); #endif } /******************************************************************************* * Function Name: Cy_RTC_EnableDstTime ****************************************************************************//** * * The function sets the DST time, configures the DST start time when the specified time is outside DST period and configures the ALARM2 interrupt register * with the appropriate DST time. This function sets the DST stop time if the * specified time is already in the DST period. The DST period is a period of time * between the DST start time and DST stop time. The DST start time and DST stop * time is presented in the DST configuration structure, * see \ref cy_stc_rtc_dst_t. * * \param dstTime * The DST configuration structure, see \ref cy_stc_rtc_dst_t. * * \param timeDate * The time and date structure. The appropriate DST time is * set based on this time and date, see \ref cy_stc_rtc_config_t. * * \return * A validation check result of RTC register update. See \ref cy_en_rtc_status_t. * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_EnableDstTime(cy_stc_rtc_dst_t const *dstTime, cy_stc_rtc_config_t const *timeDate) { cy_en_rtc_status_t retVal = CY_RTC_BAD_PARAM; if ((NULL != dstTime) && (NULL != timeDate)) { if (Cy_RTC_GetDstStatus(dstTime, timeDate)) { retVal = Cy_RTC_SetNextDstTime(&dstTime->stopDst); } else { retVal = Cy_RTC_SetNextDstTime(&dstTime->startDst); } Cy_RTC_SetInterruptMask(Cy_RTC_GetInterruptMask() | CY_RTC_INTR_ALARM2); } return (retVal); } /******************************************************************************* * Function Name: Cy_RTC_SetNextDstTime ****************************************************************************//** * * A low-level DST function sets ALARM2 for a next DST event. * If Cy_RTC_GetDSTStatus() is true(=1), the next DST event should be * the DST stop, then this function should be called with the DST stop time. * Used by the \ref Cy_RTC_EnableDstTime and \ref Cy_RTC_DstInterrupt functions. * * If the time format(.format) is relative option(=0), the * RelativeToFixed() is called to convert to a fixed date. * * \param nextDst * The structure with time at which a next DST event should occur * (ALARM2 interrupt should occur). See \ref cy_stc_rtc_config_t. * * \return * A validation check result of RTC register update. See \ref cy_en_rtc_status_t. * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_SetNextDstTime(cy_stc_rtc_dst_format_t const *nextDst) { cy_en_rtc_status_t retVal = CY_RTC_BAD_PARAM; if (NULL != nextDst) { CY_ASSERT_L3(CY_RTC_IS_DST_FORMAT_VALID(nextDst->format)); uint32_t tryesToSetup = CY_RTC_TRYES_TO_SETUP_DST; cy_stc_rtc_alarm_t dstAlarmTimeAndDate; /* Configure an alarm structure based on the DST structure */ dstAlarmTimeAndDate.sec = 0U; dstAlarmTimeAndDate.secEn = CY_RTC_ALARM_ENABLE; dstAlarmTimeAndDate.min = 0U; dstAlarmTimeAndDate.minEn = CY_RTC_ALARM_ENABLE; dstAlarmTimeAndDate.hour = nextDst->hour; dstAlarmTimeAndDate.hourEn = CY_RTC_ALARM_ENABLE; dstAlarmTimeAndDate.dayOfWeek = nextDst->dayOfWeek; dstAlarmTimeAndDate.dayOfWeekEn = CY_RTC_ALARM_DISABLE; /* Calculate a day-of-month value for the relative DST start structure */ if (CY_RTC_DST_FIXED != nextDst->format) { dstAlarmTimeAndDate.date = RelativeToFixed(nextDst); } else { dstAlarmTimeAndDate.date = nextDst->dayOfMonth; } dstAlarmTimeAndDate.dateEn = CY_RTC_ALARM_ENABLE; dstAlarmTimeAndDate.month = nextDst->month; dstAlarmTimeAndDate.monthEn = CY_RTC_ALARM_ENABLE; dstAlarmTimeAndDate.almEn = CY_RTC_ALARM_ENABLE; while((retVal != CY_RTC_SUCCESS) && (0U != tryesToSetup)) { retVal = Cy_RTC_SetAlarmDateAndTime(&dstAlarmTimeAndDate, CY_RTC_ALARM_2); --tryesToSetup; } if (tryesToSetup == 0U) { retVal = CY_RTC_TIMEOUT; } } return (retVal); } /******************************************************************************* * Function Name: Cy_RTC_GetDstStatus ****************************************************************************//** * * A low-level DST function returns the current DST status using given time * information. This function is used in the initial state of a system. * If the DST is enabled, the system sets the DST start or stop as a result of * this function. * Used by the \ref Cy_RTC_EnableDstTime and \ref Cy_RTC_DstInterrupt functions. * * \param dstTime The DST configuration structure, see \ref cy_stc_rtc_dst_t. * * \param timeDate * The time and date structure. The appropriate DST time is * set based on this time and date, see \ref cy_stc_rtc_config_t. * * \return * False - The current date and time is out of the DST period. * True - The current date and time is in the DST period. * *******************************************************************************/ bool Cy_RTC_GetDstStatus(cy_stc_rtc_dst_t const *dstTime, cy_stc_rtc_config_t const *timeDate) { uint32_t dstStartTime; uint32_t currentTime; uint32_t dstStopTime; uint32_t dstStartDayOfMonth; uint32_t dstStopDayOfMonth; bool status = false; CY_ASSERT_L1(NULL != dstTime); CY_ASSERT_L1(NULL != timeDate); /* Calculate a day-of-month value for the relative DST start structure */ if (CY_RTC_DST_RELATIVE != dstTime->startDst.format) { dstStartDayOfMonth = dstTime->startDst.dayOfMonth; } else { dstStartDayOfMonth = RelativeToFixed(&dstTime->startDst); } /* Calculate the day of a month value for the relative DST stop structure */ if (CY_RTC_DST_RELATIVE != dstTime->stopDst.format) { dstStopDayOfMonth = dstTime->stopDst.dayOfMonth; } else { dstStopDayOfMonth = RelativeToFixed(&dstTime->stopDst); } /* The function forms the date and time values for the DST start time, * the DST Stop Time and for the Current Time. The function that compares * the three formed values returns "true" under condition that: * dstStartTime < currentTime < dstStopTime. * The date and time value are formed this way: * [13-10] - Month * [9-5] - Day of Month * [0-4] - Hour */ dstStartTime = ((uint32_t) (dstTime->startDst.month << CY_RTC_DST_MONTH_POSITION) | (dstStartDayOfMonth << CY_RTC_DST_DAY_OF_MONTH_POSITION) | (dstTime->startDst.hour)); currentTime = ((uint32_t) (timeDate->month << CY_RTC_DST_MONTH_POSITION) | (timeDate->date << CY_RTC_DST_DAY_OF_MONTH_POSITION) | (timeDate->hour)); dstStopTime = ((uint32_t) (dstTime->stopDst.month << CY_RTC_DST_MONTH_POSITION) | (dstStopDayOfMonth << CY_RTC_DST_DAY_OF_MONTH_POSITION) | (dstTime->stopDst.hour)); if ((dstStartTime <= currentTime) && (dstStopTime > currentTime)) { status = true; if (1UL == (dstStopTime - currentTime)) /* Check for the 'an hour before/after stop DST event' period */ { cy_stc_rtc_alarm_t alarm; uint32_t locDate = (CY_RTC_DST_FIXED != dstTime->startDst.format) ? RelativeToFixed(&dstTime->startDst) : dstTime->startDst.dayOfMonth; Cy_RTC_GetAlarmDateAndTime(&alarm, CY_RTC_ALARM_2); /* If Alarm2 is set for the "Start DST" event - the "Stop DST" event is already passed: */ if ((alarm.almEn == CY_RTC_ALARM_ENABLE ) && (alarm.monthEn == CY_RTC_ALARM_ENABLE ) && (alarm.month == dstTime->startDst.month) && (alarm.dateEn == CY_RTC_ALARM_ENABLE ) && (alarm.date == locDate ) && (alarm.dayOfWeekEn == CY_RTC_ALARM_DISABLE ) && (alarm.hourEn == CY_RTC_ALARM_ENABLE ) && (alarm.hour == dstTime->startDst.hour ) && (alarm.minEn == CY_RTC_ALARM_ENABLE ) && (alarm.min == 0UL ) && (alarm.secEn == CY_RTC_ALARM_ENABLE ) && (alarm.sec == 0UL )) { status = false; } /* Otherwise, including the case when Alarm2 is not set at all (DST is not enabled yet) - return true. */ } } return (status); } /******************************************************************************* * Function Name: Cy_RTC_Alarm1Interrupt ****************************************************************************//** * * A blank weak interrupt handler function which indicates assert of the RTC * alarm 1 interrupt. * * Function implementation should be defined in user source code in condition * that such event handler is required. If such event is not required user * should not do any actions. * * This function is called in the general RTC interrupt handler * Cy_RTC_Interrupt() function. * *******************************************************************************/ __WEAK void Cy_RTC_Alarm1Interrupt(void) { /* weak blank function */ } /******************************************************************************* * Function Name: Cy_RTC_Alarm2Interrupt ****************************************************************************//** * * A blank weak interrupt handler function which indicates assert of the RTC * alarm 2 interrupt. * * Function implementation should be defined in user source code in condition * that such event handler is required. If such event is not required user * should not do any actions. * * This function is called in the general RTC interrupt handler * Cy_RTC_Interrupt() function. Cy_RTC_Alarm2Interrupt() function is * ignored in Cy_RTC_Interrupt() function if DST is enabled. Refer to * Cy_RTC_Interrupt() description. * *******************************************************************************/ __WEAK void Cy_RTC_Alarm2Interrupt(void) { /* weak blank function */ } /******************************************************************************* * Function Name: Cy_RTC_DstInterrupt ****************************************************************************//** * * This is a processing handler against the DST event. It adjusts the current * time using the DST start/stop parameters and registers the next DST event time * into the ALARM2 interrupt. This function is already called by \ref Cy_RTC_Interrupt(). * * \param dstTime The DST configuration structure, see \ref cy_stc_rtc_dst_t. * *******************************************************************************/ void Cy_RTC_DstInterrupt(cy_stc_rtc_dst_t const *dstTime) { cy_stc_rtc_config_t curDateTime; Cy_RTC_GetDateAndTime(&curDateTime); if (Cy_RTC_GetDstStatus(dstTime, &curDateTime)) { /* Under condition that the DST start time was selected as 23:00, and * the time adjusting occurs, the other time and date values should be * corrected (day of the week, date, month and year). */ if (curDateTime.hour == CY_RTC_MAX_HOURS_24H) { /* Incrementing day of the week value as hour adjusted next day of * the week and date. Correcting hour value as its incrementation * adjusted it out of valid range [0-23]. */ curDateTime.dayOfWeek++; curDateTime.hour = 0U; /* Correct a day of the week if its incrementation adjusted it out * of valid range [1-7]. */ if (curDateTime.dayOfWeek > CY_RTC_SATURDAY) { curDateTime.dayOfWeek = CY_RTC_SUNDAY; } curDateTime.date++; /* Correct a day of a month if its incrementation adjusted it out of * the valid range [1-31]. Increment month value. */ if (curDateTime.date > Cy_RTC_DaysInMonth(curDateTime.month, (curDateTime.year + CY_RTC_TWO_THOUSAND_YEARS))) { curDateTime.date = CY_RTC_FIRST_DAY_OF_MONTH; curDateTime.month++; } /* Correct a month if its incrementation adjusted it out of the * valid range [1-12]. Increment year value. */ if (curDateTime.month > CY_RTC_MONTHS_PER_YEAR) { curDateTime.month = CY_RTC_JANUARY; curDateTime.year++; } } else { curDateTime.hour++; } (void) Cy_RTC_SetDateAndTime(&curDateTime); (void) Cy_RTC_SetNextDstTime(&dstTime->stopDst); } else { if (curDateTime.hour < 1U) { /* Decrementing day of the week time and date values as hour * adjusted next day of the week and date. Correct hour value as * its incrementation adjusted it out of valid range [0-23]. */ curDateTime.hour = CY_RTC_MAX_HOURS_24H; curDateTime.dayOfWeek--; /* Correct a day of the week if its incrementation adjusted it out * of the valid range [1-7]. */ if (curDateTime.dayOfWeek < CY_RTC_SUNDAY) { curDateTime.dayOfWeek = CY_RTC_SUNDAY; } curDateTime.date--; /* Correct a day of a month value if its incrementation adjusted it * out of the valid range [1-31]. Decrement month value. */ if (curDateTime.date < CY_RTC_FIRST_DAY_OF_MONTH) { curDateTime.month--; curDateTime.date = Cy_RTC_DaysInMonth(curDateTime.month, (curDateTime.year + CY_RTC_TWO_THOUSAND_YEARS)); } /* Correct a month if its increment pushed it out of the valid * range [1-12]. Decrement year value. */ if (curDateTime.month < CY_RTC_JANUARY) { curDateTime.month = CY_RTC_DECEMBER; curDateTime.year--; } } else { curDateTime.hour--; } (void) Cy_RTC_SetDateAndTime(&curDateTime); (void) Cy_RTC_SetNextDstTime(&dstTime->startDst); } } /******************************************************************************* * Function Name: Cy_RTC_CenturyInterrupt ****************************************************************************//** * * This is a weak function and it should be redefined in user source code * in condition that such event handler is required. * By calling this function, it indicates the year reached 2100. * * Function implementation should be defined in user source code in condition * that such event handler is required. If such event is not required user * should not do any actions. * *******************************************************************************/ __WEAK void Cy_RTC_CenturyInterrupt(void) { /* weak blank function */ } /******************************************************************************* * Function Name: Cy_RTC_GetInterruptStatus ****************************************************************************//** * * Returns a status of RTC interrupt requests. * * \return * Bit mapping information, see \ref group_rtc_macros_interrupts. * *******************************************************************************/ uint32_t Cy_RTC_GetInterruptStatus(void) { return(BACKUP_INTR); } /******************************************************************************* * Function Name: Cy_RTC_GetInterruptStatusMasked ****************************************************************************//** * * Returns an interrupt request register masked by the interrupt mask. Returns a * result of the bitwise AND operation between the corresponding interrupt * request and mask bits. * * \return * Bit mapping information, see \ref group_rtc_macros_interrupts. * *******************************************************************************/ uint32_t Cy_RTC_GetInterruptStatusMasked(void) { return(BACKUP_INTR_MASKED); } /******************************************************************************* * Function Name: Cy_RTC_GetInterruptMask ****************************************************************************//** * * Returns an interrupt mask. * * \return * Bit mapping information, see \ref group_rtc_macros_interrupts. * *******************************************************************************/ uint32_t Cy_RTC_GetInterruptMask(void) { return (BACKUP_INTR_MASK); } /******************************************************************************* * Function Name: Cy_RTC_SetInterrupt ****************************************************************************//** * * Sets a software interrupt request * * \param interruptMask * Bit mask, see \ref group_rtc_macros_interrupts. * *******************************************************************************/ void Cy_RTC_SetInterrupt(uint32_t interruptMask) { CY_ASSERT_L3(CY_RTC_INTR_VALID(interruptMask)); BACKUP_INTR_SET = interruptMask; } /******************************************************************************* * Function Name: Cy_RTC_ClearInterrupt ****************************************************************************//** * * Clears RTC interrupts by setting each bit. * * \param * interruptMask The bit mask of interrupts to set, * see \ref group_rtc_macros_interrupts. * *******************************************************************************/ void Cy_RTC_ClearInterrupt(uint32_t interruptMask) { CY_ASSERT_L3(CY_RTC_INTR_VALID(interruptMask)); (void) BACKUP_INTR; BACKUP_INTR = interruptMask; } /******************************************************************************* * Function Name: Cy_RTC_SetInterruptMask ****************************************************************************//** * * Configures which bits of the interrupt request register that triggers an * interrupt event. * * \param interruptMask * The bit mask of interrupts to set, see \ref group_rtc_macros_interrupts. * *******************************************************************************/ void Cy_RTC_SetInterruptMask(uint32_t interruptMask) { CY_ASSERT_L3(CY_RTC_INTR_VALID(interruptMask)); BACKUP_INTR_MASK = interruptMask; } /******************************************************************************* * Function Name: Cy_RTC_Interrupt ****************************************************************************//** * * The interrupt handler function which should be called in user provided * RTC interrupt function. * * This is the handler of the RTC interrupt in CPU NVIC. The handler checks * which RTC interrupt was asserted and calls the respective RTC interrupt * handler functions: Cy_RTC_Alarm1Interrupt(), Cy_RTC_Alarm2Interrupt() or * Cy_RTC_DstInterrupt(), and Cy_RTC_CenturyInterrupt(). * * The order of the RTC handler functions execution is incremental. * Cy_RTC_Alarm1Interrupt() is run as the first one and Cy_RTC_CenturyInterrupt() * is called as the last one. * * This function clears the RTC interrupt every time when it is called. * * Cy_RTC_DstInterrupt() function is called instead of Cy_RTC_Alarm2Interrupt() * in condition that the mode parameter is true. * * \param dstTime * The daylight saving time configuration structure, see \ref cy_stc_rtc_dst_t. * * \param mode * False - if the DST is disabled. * True - if DST is enabled. * * \note This function is required to be called in user interrupt handler. * *******************************************************************************/ void Cy_RTC_Interrupt(cy_stc_rtc_dst_t const *dstTime, bool mode) { uint32_t interruptStatus; interruptStatus = Cy_RTC_GetInterruptStatusMasked(); Cy_RTC_ClearInterrupt(interruptStatus); if (0U != (CY_RTC_INTR_ALARM1 & interruptStatus)) { Cy_RTC_Alarm1Interrupt(); } if (0U != (CY_RTC_INTR_ALARM2 & interruptStatus)) { if (mode) { Cy_RTC_DstInterrupt(dstTime); } else { Cy_RTC_Alarm2Interrupt(); } } if (0U != (CY_RTC_INTR_CENTURY & interruptStatus)) { Cy_RTC_CenturyInterrupt(); } } /******************************************************************************* * Function Name: Cy_RTC_DeepSleepCallback ****************************************************************************//** * * This function checks the RTC_BUSY bit to avoid data corruption before * enters the Deep Sleep mode. * * \param callbackParams * The structure with the SysPm callback parameters, * see \ref cy_stc_syspm_callback_params_t * * \param mode * Callback mode, see \ref cy_en_syspm_callback_mode_t. * * \return * The SysPm return status, see \ref cy_en_syspm_status_t. * * \note The *base and *context elements are required to be present in * the parameter structure because this function uses the SysPm driver * callback type. * The SysPm driver callback function type requires implementing the function * with next parameters and return value: * * cy_en_syspm_status_t (*Cy_SysPmCallback) * (cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode); * *******************************************************************************/ cy_en_syspm_status_t Cy_RTC_DeepSleepCallback(const cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode) { cy_en_syspm_status_t retVal = CY_SYSPM_FAIL; if (callbackParams != NULL) { switch(mode) { case CY_SYSPM_CHECK_READY: { if (CY_RTC_AVAILABLE == Cy_RTC_GetSyncStatus()) { retVal = CY_SYSPM_SUCCESS; } } break; case CY_SYSPM_CHECK_FAIL: { retVal = CY_SYSPM_SUCCESS; } break; case CY_SYSPM_BEFORE_TRANSITION: { retVal = CY_SYSPM_SUCCESS; } break; case CY_SYSPM_AFTER_TRANSITION: { retVal = CY_SYSPM_SUCCESS; } break; default: /* Unknown state */ break; } } return (retVal); } /******************************************************************************* * Function Name: Cy_RTC_HibernateCallback ****************************************************************************//** * * This function checks the RTC_BUSY bit to avoid data corruption before * enters the Hibernate mode. * * \param callbackParams * structure with the syspm callback parameters, * see \ref cy_stc_syspm_callback_params_t. * * \param mode * Callback mode, see \ref cy_en_syspm_callback_mode_t * * \return * The syspm return status, see \ref cy_en_syspm_status_t * * \note The *base and *context elements are required to be present in * the parameter structure because this function uses the SysPm driver * callback type. * The SysPm driver callback function type requires implementing the function * with next parameters and return value: * * cy_en_syspm_status_t (*Cy_SysPmCallback) * (cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode); * *******************************************************************************/ cy_en_syspm_status_t Cy_RTC_HibernateCallback(const cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode) { return (Cy_RTC_DeepSleepCallback(callbackParams, mode)); } /******************************************************************************* * Function Name: Cy_RTC_CalibrationControlEnable ****************************************************************************//** * * This function writes calibration control register. * * \param calib_val * Calibration value for absolute frequency (at a fixed temperature). * Each step causes 128 ticks to be added or removed each hour. * * \param calib_sign * Remove or Add ticks, see \ref cy_en_rtc_calib_sign_t * * \param calib_sel * Select calibration wave output signal, see \ref cy_en_rtc_calib_sel_t * * \return * The RTC return status, see \ref cy_en_rtc_status_t * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_CalibrationControlEnable(uint8_t calib_val, cy_en_rtc_calib_sign_t calib_sign, cy_en_rtc_calib_sel_t calib_sel) { cy_en_rtc_status_t retVal = CY_RTC_INVALID_STATE; uint32_t interruptState; CY_UNUSED_PARAMETER(calib_sel); /* The RTC AHB registers can be updated only under condition that the * Write bit is set and the RTC busy bit is cleared (RTC_BUSY = 0). */ interruptState = Cy_SysLib_EnterCriticalSection(); retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_ENABLED); if (CY_RTC_SUCCESS == retVal) { BACKUP_CAL_CTL = _VAL2FLD(BACKUP_CAL_CTL_CALIB_VAL, calib_val) | _VAL2FLD(BACKUP_CAL_CTL_CALIB_SIGN, (uint32_t)calib_sign) | #if defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS_RTC_VERSION) && (CY_IP_MXS40SRSS_RTC_VERSION >= 2)) _VAL2FLD(BACKUP_CAL_CTL_CAL_SEL, (uint32_t)calib_sel) | #endif _VAL2FLD(BACKUP_CAL_CTL_CAL_OUT, 1U); /* Clear the RTC Write bit to finish RTC update */ retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_DISABLED); } Cy_SysLib_ExitCriticalSection(interruptState); return(retVal); } /******************************************************************************* * Function Name: Cy_RTC_CalibrationControlDisable ****************************************************************************//** * * This function disables the calibration control. * * \return * The RTC return status, see \ref cy_en_rtc_status_t * *******************************************************************************/ cy_en_rtc_status_t Cy_RTC_CalibrationControlDisable(void) { cy_en_rtc_status_t retVal = CY_RTC_INVALID_STATE; uint32_t interruptState; /* The RTC AHB registers can be updated only under condition that the * Write bit is set and the RTC busy bit is cleared (RTC_BUSY = 0). */ interruptState = Cy_SysLib_EnterCriticalSection(); retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_ENABLED); if (CY_RTC_SUCCESS == retVal) { BACKUP_CAL_CTL = _VAL2FLD(BACKUP_CAL_CTL_CAL_OUT, 0U); /* Clear the RTC Write bit to finish RTC update */ retVal = Cy_RTC_WriteEnable(CY_RTC_WRITE_DISABLED); } Cy_SysLib_ExitCriticalSection(interruptState); return(retVal); } /******************************************************************************* * Function Name: ConstructTimeDate ****************************************************************************//** * * Returns BCD time and BCD date in the format used in APIs from individual * elements passed. * Converted BCD time(*timeBcd) and BCD date(*dateBcd) are matched with RTC_TIME * and RTC_DATE bit fields format. * * \param timeDate * The structure of time and date, see \ref cy_stc_rtc_config_t. * * \param timeBcd * The BCD-formatted time variable which has the same bit masks as the * RTC_TIME register: * * [0:6] - Calendar seconds in BCD, the range 0-59. \n * [14:8] - Calendar minutes in BCD, the range 0-59. \n * [21:16] - Calendar hours in BCD, value depends on the 12/24-hour mode. \n * 12HR: [21]:0 = AM, 1 = PM, [20:16] = 1 - 12; \n * 24HR: [21:16] = 0-23. \n * [22] - Selects the 12/24-hour mode: 1 - 12-hour, 0 - 24-hour. \n * [26:24] - A calendar day of the week, the range 1 - 7, where 1 - Sunday. \n * * \param dateBcd * The BCD-formatted time variable which has the same bit masks as the * RTC_DATE register: * * [5:0] - A calendar day of a month in BCD, the range 1-31. \n * [12:8] - A calendar month in BCD, the range 1-12. \n * [23:16] - A calendar year in BCD, the range 0-99. \n * *******************************************************************************/ static void ConstructTimeDate(cy_stc_rtc_config_t const *timeDate, uint32_t *timeBcd, uint32_t *dateBcd) { uint32_t tmpTime; uint32_t tmpDate; /* Prepare the RTC TIME value based on the structure obtained */ tmpTime = (_VAL2FLD(BACKUP_RTC_TIME_RTC_SEC, CONVERT_DEC_TO_BCD(timeDate->sec))); tmpTime |= (_VAL2FLD(BACKUP_RTC_TIME_RTC_MIN, CONVERT_DEC_TO_BCD(timeDate->min))); /* Read the current hour mode to know how many hour bits to convert. * In the 24-hour mode, the hour value is presented in [21:16] bits in the * BCD format. * In the 12-hour mode, the hour value is presented in [20:16] bits in the * BCD format and bit [21] is present: 0 - AM; 1 - PM. */ if (timeDate->hrFormat != CY_RTC_24_HOURS) { if (CY_RTC_AM != timeDate->amPm) { /* Set the PM bit */ tmpTime |= CY_RTC_BACKUP_RTC_TIME_RTC_PM; } else { /* Set the AM bit */ tmpTime &= ((uint32_t) ~CY_RTC_BACKUP_RTC_TIME_RTC_PM); } tmpTime |= BACKUP_RTC_TIME_CTRL_12HR_Msk; tmpTime |= (_VAL2FLD(BACKUP_RTC_TIME_RTC_HOUR, (CONVERT_DEC_TO_BCD(timeDate->hour) & ((uint32_t) ~CY_RTC_12HRS_PM_BIT)))); } else { tmpTime &= ((uint32_t) ~BACKUP_RTC_TIME_CTRL_12HR_Msk); tmpTime |= (_VAL2FLD(BACKUP_RTC_TIME_RTC_HOUR, CONVERT_DEC_TO_BCD(timeDate->hour))); } if (timeDate->dayOfWeek == CY_RTC_DAY_AUTO) { tmpTime |= (_VAL2FLD(BACKUP_RTC_TIME_RTC_DAY, CONVERT_DEC_TO_BCD(Cy_RTC_ConvertDayOfWeek(timeDate->date, timeDate->month, (timeDate->year + CY_RTC_TWO_THOUSAND_YEARS))))); } else { tmpTime |= (_VAL2FLD(BACKUP_RTC_TIME_RTC_DAY, CONVERT_DEC_TO_BCD(timeDate->dayOfWeek))); } /* Prepare the RTC Date value based on the structure obtained */ tmpDate = (_VAL2FLD(BACKUP_RTC_DATE_RTC_DATE, CONVERT_DEC_TO_BCD(timeDate->date))); tmpDate |= (_VAL2FLD(BACKUP_RTC_DATE_RTC_MON, CONVERT_DEC_TO_BCD(timeDate->month))); tmpDate |= (_VAL2FLD(BACKUP_RTC_DATE_RTC_YEAR, CONVERT_DEC_TO_BCD(timeDate->year))); /* Update the parameter values with prepared values */ *timeBcd = tmpTime; *dateBcd = tmpDate; } /******************************************************************************* * Function Name: ConstructAlarmTimeDate ****************************************************************************//** * * Returns the BCD time and BCD date in the format used in APIs from individual * elements passed for alarm. * Converted BCD time(*alarmTimeBcd) and BCD date(*alarmDateBcd) should be * matched with the ALMx_TIME and ALMx_DATE bit fields format. * * \param alarmDateTime * The structure of time and date, see \ref cy_stc_rtc_alarm_t. * * \param alarmTimeBcd * The BCD-formatted time variable which has the same bit masks as the * ALMx_TIME register time fields: * * [0:6] - Alarm seconds in BCD, the range 0-59. \n * [7] - Alarm seconds Enable: 0 - ignore, 1 - match. \n * [14:8] - Alarm minutes in BCD, the range 0-59. \n * [15] - Alarm minutes Enable: 0 - ignore, 1 - match. \n * [21:16] - Alarm hours in BCD, value depending on the 12/24-hour mode * (RTC_CTRL_12HR) \n * 12HR: [21]:0 = AM, 1 = PM, [20:16] = 1 - 12; \n * 24HR: [21:16] = the range 0-23. \n * [23] - Alarm hours Enable: 0 - ignore, 1 - match. \n * [26:24] - An alarm day of the week, the range 1 - 7, where 1 - Monday. \n * [31] - An alarm day of the week Enable: 0 - ignore, 1 - match. \n * * \param alarmDateBcd * The BCD-formatted date variable which has the same bit masks as the * ALMx_DATE register date fields: * * [5:0] - An alarm day of a month in BCD, the range 1-31. \n * [7] - An alarm day of a month Enable: 0 - ignore, 1 - match. \n * [12:8] - An alarm month in BCD, the range 1-12. \n * [15] - An alarm month Enable: 0 - ignore, 1 - match. \n * [31] - The Enable alarm: 0 - Alarm is disabled, 1 - Alarm is enabled. \n * * This function reads current AHB register RTC_TIME value to know hour mode. * It is recommended to call Cy_RTC_SyncFromRtc() function before calling the * ConstructAlarmTimeDate() functions. * * Construction is based on RTC_ALARM1 register bit fields. * *******************************************************************************/ static void ConstructAlarmTimeDate(cy_stc_rtc_alarm_t const *alarmDateTime, uint32_t *alarmTimeBcd, uint32_t *alarmDateBcd) { uint32_t tmpAlarmTime; uint32_t tmpAlarmDate; uint32_t hourValue; /* Prepare the RTC ALARM value based on the structure obtained */ tmpAlarmTime = (_VAL2FLD(BACKUP_ALM1_TIME_ALM_SEC, CONVERT_DEC_TO_BCD(alarmDateTime->sec))); tmpAlarmTime |= (_VAL2FLD(BACKUP_ALM1_TIME_ALM_SEC_EN, alarmDateTime->secEn)); tmpAlarmTime |= (_VAL2FLD(BACKUP_ALM1_TIME_ALM_MIN, CONVERT_DEC_TO_BCD(alarmDateTime->min))); tmpAlarmTime |= (_VAL2FLD(BACKUP_ALM1_TIME_ALM_MIN_EN, alarmDateTime->minEn)); /* Read the current hour mode to know how many hour bits to convert. * In the 24-hour mode, the hour value is presented in [21:16] bits in the * BCD format. * In the 12-hour mode, the hour value is presented in [20:16] bits in the * BCD format and bit [21] is present: 0 - AM; 1 - PM */ Cy_RTC_SyncFromRtc(); if (CY_RTC_24_HOURS != Cy_RTC_GetHoursFormat()) { /* Convert the hour from the 24-hour mode into the 12-hour mode */ if (alarmDateTime->hour >= CY_RTC_HOURS_PER_HALF_DAY) { /* The current hour is more than 12 in the 24-hour mode. Set the PM * bit and converting hour: hour = hour - 12 */ hourValue = (uint32_t) alarmDateTime->hour - CY_RTC_HOURS_PER_HALF_DAY; hourValue = ((0U != hourValue) ? hourValue : CY_RTC_HOURS_PER_HALF_DAY); tmpAlarmTime |= CY_RTC_BACKUP_RTC_TIME_RTC_PM | (_VAL2FLD(BACKUP_ALM1_TIME_ALM_HOUR, CONVERT_DEC_TO_BCD(hourValue))); } else if (alarmDateTime->hour < 1U) { /* The current hour in the 24-hour mode is 0 which is equal to 12:00 AM */ tmpAlarmTime = (tmpAlarmTime & ((uint32_t) ~CY_RTC_BACKUP_RTC_TIME_RTC_PM)) | (_VAL2FLD(BACKUP_ALM1_TIME_ALM_HOUR, CY_RTC_HOURS_PER_HALF_DAY)); } else { /* The current hour is less than 12. Set the AM bit */ tmpAlarmTime = (tmpAlarmTime & ((uint32_t) ~CY_RTC_BACKUP_RTC_TIME_RTC_PM)) | (_VAL2FLD(BACKUP_ALM1_TIME_ALM_HOUR, CONVERT_DEC_TO_BCD(alarmDateTime->hour))); } tmpAlarmTime |= BACKUP_RTC_TIME_CTRL_12HR_Msk; } else { tmpAlarmTime |= (_VAL2FLD(BACKUP_ALM1_TIME_ALM_HOUR, CONVERT_DEC_TO_BCD(alarmDateTime->hour))); tmpAlarmTime &= ((uint32_t) ~BACKUP_RTC_TIME_CTRL_12HR_Msk); } tmpAlarmTime |= (_VAL2FLD(BACKUP_ALM1_TIME_ALM_HOUR_EN, alarmDateTime->hourEn)); tmpAlarmTime |= (_VAL2FLD(BACKUP_ALM1_TIME_ALM_DAY, CONVERT_DEC_TO_BCD(alarmDateTime->dayOfWeek))); tmpAlarmTime |= (_VAL2FLD(BACKUP_ALM1_TIME_ALM_DAY_EN, alarmDateTime->dayOfWeekEn)); /* Prepare the RTC ALARM DATE value based on the obtained structure */ tmpAlarmDate = (_VAL2FLD(BACKUP_ALM1_DATE_ALM_DATE, CONVERT_DEC_TO_BCD(alarmDateTime->date))); tmpAlarmDate |= (_VAL2FLD(BACKUP_ALM1_DATE_ALM_DATE_EN, alarmDateTime->dateEn)); tmpAlarmDate |= (_VAL2FLD(BACKUP_ALM1_DATE_ALM_MON, CONVERT_DEC_TO_BCD(alarmDateTime->month))); tmpAlarmDate |= (_VAL2FLD(BACKUP_ALM1_DATE_ALM_MON_EN, alarmDateTime->monthEn)); tmpAlarmDate |= (_VAL2FLD(BACKUP_ALM1_DATE_ALM_EN, alarmDateTime->almEn)); /* Update the parameter values with prepared values */ *alarmTimeBcd = tmpAlarmTime; *alarmDateBcd = tmpAlarmDate; } /******************************************************************************* * Function Name: RelativeToFixed ****************************************************************************//** * * Converts time from a relative format to a fixed format to set the ALARM2. * * \param convertDst * The DST structure, its appropriate elements should be converted. * * \return * The current date of a month. * *******************************************************************************/ static uint32_t RelativeToFixed(cy_stc_rtc_dst_format_t const *convertDst) { uint32_t currentYear; uint32_t currentDay; uint32_t currentWeek; uint32_t daysInMonth; uint32_t tmpDayOfMonth; /* Read the current year */ Cy_RTC_SyncFromRtc(); currentYear = CY_RTC_TWO_THOUSAND_YEARS + CONVERT_BCD_TO_DEC(_FLD2VAL(BACKUP_RTC_DATE_RTC_YEAR, BACKUP_RTC_DATE)); currentDay = CY_RTC_FIRST_DAY_OF_MONTH; currentWeek = CY_RTC_FIRST_WEEK_OF_MONTH; daysInMonth = Cy_RTC_DaysInMonth(convertDst->month, currentYear); tmpDayOfMonth = currentDay; while((currentWeek <= convertDst->weekOfMonth) && (currentDay <= daysInMonth)) { if (convertDst->dayOfWeek == Cy_RTC_ConvertDayOfWeek(currentDay, convertDst->month, currentYear)) { tmpDayOfMonth = currentDay; currentWeek++; } currentDay++; } return(tmpDayOfMonth); } #if defined(__cplusplus) } #endif CY_MISRA_BLOCK_END('MISRA C-2012 Rule 2.2') #endif /* CY_IP_MXS40SRSS_RTC, CY_IP_MXS28SRSS, CY_IP_MXS40SSRSS */ /* [] END OF FILE */