Newer
Older
mbed-os / targets / TARGET_Samsung / TARGET_SIDK_S1SBP6A / rtc_api.c
@Heuisam Kwag Heuisam Kwag on 11 Aug 2020 2 KB introduce S1SBP6A
/****************************************************************************
 *
 * Copyright 2020 Samsung Electronics All Rights Reserved.
 * 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.
 *
 ****************************************************************************/

/****************************************************************************
 * Included Files
 ****************************************************************************/
#if DEVICE_RTC
#include <stdlib.h>
#include "cmsis.h"
#include "rtc_api.h"
#include "mbed_mktime.h"
#include "mbed_critical.h"
#include "mbed_error.h"
#include "mbed_debug.h"

#define BP6A_RTC_START_TIME     946684800
static bool rtc_initialized = false;
static bool g_before2000 = false;

void rtc_init(void)
{
    if (!rtc_initialized) {
        uint32_t sys_clk = bp6a_cmu_get_clock_freq(CMU_FCLK_AHBCLK);

        bp6a_set_rtc_delay((uint32_t)((float)sys_clk * 2 / 32789));
        bp6a_rtc_init();
        rtc_initialized = true;
    }
}

void rtc_free(void)
{
    rtc_initialized = 0;
}

int rtc_isenabled(void)
{
    return 1;
}

time_t rtc_read(void)
{
    struct rtc_bcd_s rtc_val;
    struct tm timeinfo;
    time_t t;

    bp6a_rtc_getdatetime(&rtc_val);

    timeinfo.tm_sec = bp6a_rtc_bcd2bin(rtc_val.sec);
    timeinfo.tm_min = bp6a_rtc_bcd2bin(rtc_val.min);
    timeinfo.tm_hour = bp6a_rtc_bcd2bin(rtc_val.hour);
    timeinfo.tm_mday = bp6a_rtc_bcd2bin(rtc_val.day);
    timeinfo.tm_mon = bp6a_rtc_bcd2bin(rtc_val.mon);
    timeinfo.tm_year = bp6a_rtc_bcd2bin(rtc_val.year);
    timeinfo.tm_year += 100;
    if (_rtc_maketime(&timeinfo, &t, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
        return 0;
    }

    if (g_before2000) {
        t -= BP6A_RTC_START_TIME;
    }
    return t;
}

void rtc_write(time_t t)
{
    struct rtc_bcd_s rtc_val;
    struct tm timeinfo;

    /*BP6A : The implicit number of thousands place is 20.*/
    if (t < BP6A_RTC_START_TIME) {
        g_before2000 = true;
        t += BP6A_RTC_START_TIME;
    } else {
        g_before2000 = false;
    }


    if (_rtc_localtime(t, &timeinfo, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
        return;
    }

    rtc_val.sec = timeinfo.tm_sec;
    rtc_val.min = timeinfo.tm_min;
    rtc_val.hour = timeinfo.tm_hour;
    rtc_val.day = timeinfo.tm_mday;
    rtc_val.mon = timeinfo.tm_mon;
    rtc_val.year = timeinfo.tm_year - 100;

    bp6a_rtc_setdatetime(&rtc_val);

}

#endif /* DEVICE_RTC */