/* * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved. * 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. */ /** * @file wm_rtc.c * * @brief rtc Driver Module * * @author dave * * Copyright (c) 2014 Winner Microelectronics Co., Ltd. */ #include #include #include #include "wm_regs.h" #include "wm_rtc.h" #include "wm_irq.h" #include "tls_common.h" struct rtc_irq_context { tls_rtc_irq_callback callback; void *arg; }; static struct rtc_irq_context rtc_context = {0}; /** * @brief This function is used to set pmu rtc time * * @param[in] tblock time value * * @return None * * @note None */ void tls_set_rtc(struct tm *tblock) { int ctrl1 = 0; int ctrl2 = 0; ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2); /* disable */ ctrl2 &= ~(1 << 16); tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2); ctrl1 |= tblock->tm_sec; ctrl1 |= tblock->tm_min << 8; ctrl1 |= tblock->tm_hour << 16; ctrl1 |= tblock->tm_mday << 24; tls_reg_write32(HR_PMU_RTC_CTRL1, ctrl1); ctrl2 = 0; ctrl2 |= tblock->tm_mon; ctrl2 |= tblock->tm_year << 8; tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2); ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2); /* enable */ ctrl2 |= (1 << 16); tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2); } /** * @brief This function is used to get pmu rtc time * * @param[out] tblock time value * * @return None * * @note None */ void tls_get_rtc(struct tm *tblock) { int ctrl1 = 0; int ctrl2 = 0; ctrl1 = tls_reg_read32(HR_PMU_RTC_CTRL1); ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2); tblock->tm_year = ((int)((int)ctrl2 & 0x00007f00) >> 8); tblock->tm_mon = (ctrl2 & 0x0000000f); tblock->tm_mday = (ctrl1 & 0x1f000000) >> 24; tblock->tm_hour = (ctrl1 & 0x001f0000) >> 16; tblock->tm_min = (ctrl1 & 0x00003f00) >> 8; tblock->tm_sec = ctrl1 & 0x0000003f; } void PMU_RTC_IRQHandler(void) { tls_reg_write32(HR_PMU_INTERRUPT_SRC, BIT(4)); /* clear rtc interrupt */ if (rtc_context.callback != NULL) rtc_context.callback(rtc_context.arg); return; } /** * @brief This function is used to register pmu rtc interrupt * * @param[in] callback the rtc interrupt call back function * @param[in] arg parameter of call back function * * @return None * * @note * user not need clear interrupt flag. * rtc callback function is called in interrupt, * so can not operate the critical data in the callback fuuction, * recommendation to send messages to other tasks to operate it. */ void tls_rtc_isr_register(tls_rtc_irq_callback callback, void *arg) { rtc_context.callback = callback; rtc_context.arg = arg; tls_irq_enable(PMU_IRQn); return; } /** * @brief This function is used to start pmu rtc timer * * @param[in] tblock timer value * * @return None * * @note None */ void tls_rtc_timer_start(struct tm *tblock) { int ctrl1 = 0; int ctrl2 = 0; tls_irq_enable(PMU_IRQn); ctrl1 |= tblock->tm_sec; ctrl1 |= tblock->tm_min << 8; ctrl1 |= tblock->tm_hour << 16; ctrl1 |= tblock->tm_mday << 24; ctrl2 |= tblock->tm_mon; ctrl2 |= tblock->tm_year << 8; tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2 | BIT(16)); tls_reg_write32(HR_PMU_RTC_CTRL1, ctrl1 | BIT(31)); /* must set the enable */ return; } /** * @brief This function is used to stop pmu rtc timer * * @param None * * @return None * * @note This function also is used to clear rtc timer interrupt */ void tls_rtc_timer_stop(void) { tls_reg_write32(HR_PMU_RTC_CTRL1, tls_reg_read32(HR_PMU_RTC_CTRL1) & (~BIT(31))); return; }