// RTC业务驱动
// 杭州秒寻科技有限公司
// 周涛
// 2025-02-28

#include "includes.h"

// 写数据
uint8 driverapp_rtc_write_data(uint8 byRegAddress, uint8 *pbyData, uint16 wLen)
{
    uint8 byFlag = 0;

    byFlag = driver_rtci2c_write_data(RTC_SLAVE_ADDRESS, byRegAddress, pbyData, wLen);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 读数据
uint8 driverapp_rtc_read_data(uint8 byRegAddress, uint8 *pbyData, uint16 wLen)
{
    uint8 byFlag = 0;

    byFlag = driver_rtci2c_read_data(RTC_SLAVE_ADDRESS, byRegAddress, pbyData, wLen);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// RTC初始化
uint8 driverapp_rtc_init()
{
    uint8 byFlag = 0;

    uint8 byYear = 0;
    uint8 byMonth = 0;
    uint8 byDay = 0;
    uint8 byHour = 0;
    uint8 byMinute = 0;
    uint8 bySecond = 0;

    byFlag = driverapp_rtc_get_current_datetime(&byYear, &byMonth, &byDay, &byHour, &byMinute, &bySecond);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 配置RTC初始时间
uint8 driverapp_rtc_set_init_time()
{
    uint8 byInData = 0;
    uint8 byOutData = 0;

    // 秒
    byInData = driverapp_rtc_decimal_to_bcd(17);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_SECOND, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_SECOND, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 分
    byInData = driverapp_rtc_decimal_to_bcd(16);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_MINUTE, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_MINUTE, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 小时
    byInData = driverapp_rtc_decimal_to_bcd(15);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_HOUR, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_HOUR, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 日
    byInData = driverapp_rtc_decimal_to_bcd(14);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_DAY, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_DAY, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 月
    byInData = driverapp_rtc_decimal_to_bcd(6);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_MONTH, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_MONTH, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 年
    byInData = driverapp_rtc_decimal_to_bcd(23);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_YEAR, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_YEAR, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    return 1;
}

// 读取当前小时和分钟
uint8 driverapp_rtc_read_hour_minute(uint8 *pbyHour, uint8 *pbyMinute)
{
    uint8 byFlag = 0;
    uint8 byTmp = 0;

    byFlag = driverapp_rtc_read_data(RTC_REG_ADDRESS_HOUR, &byTmp, 1);
    if (!byFlag)
    {
        return byFlag;
    }
    *pbyHour = driverapp_rtc_bcd_to_decimal(byTmp);

    byFlag = driverapp_rtc_read_data(RTC_REG_ADDRESS_MINUTE, &byTmp, 1);
    if (!byFlag)
    {
        return byFlag;
    }
    *pbyMinute = driverapp_rtc_bcd_to_decimal(byTmp);

    return 1;
}

// 读取当前时间，包括年月日时分
uint8 driverapp_rtc_get_current_datetime(uint8 *pbyYear, uint8 *pbyMonth, uint8 *pbyDay, uint8 *pbyHour, uint8 *pbyMinute, uint8 *pbySecond)
{
    uint8 byFlag = 0;
    uint8 byTmp = 0;

    byFlag = driverapp_rtc_read_data(RTC_REG_ADDRESS_YEAR, &byTmp, 1);
    if (!byFlag)
    {
        return byFlag;
    }
    *pbyYear = driverapp_rtc_bcd_to_decimal(byTmp);

    byFlag = driverapp_rtc_read_data(RTC_REG_ADDRESS_MONTH, &byTmp, 1);
    if (!byFlag)
    {
        return byFlag;
    }
    *pbyMonth = driverapp_rtc_bcd_to_decimal(byTmp);

    byFlag = driverapp_rtc_read_data(RTC_REG_ADDRESS_DAY, &byTmp, 1);
    if (!byFlag)
    {
        return byFlag;
    }
    *pbyDay = driverapp_rtc_bcd_to_decimal(byTmp);

    byFlag = driverapp_rtc_read_data(RTC_REG_ADDRESS_HOUR, &byTmp, 1);
    if (!byFlag)
    {
        return byFlag;
    }
    *pbyHour = driverapp_rtc_bcd_to_decimal(byTmp);

    byFlag = driverapp_rtc_read_data(RTC_REG_ADDRESS_MINUTE, &byTmp, 1);
    if (!byFlag)
    {
        return byFlag;
    }
    *pbyMinute = driverapp_rtc_bcd_to_decimal(byTmp);

    byFlag = driverapp_rtc_read_data(RTC_REG_ADDRESS_SECOND, &byTmp, 1);
    if (!byFlag)
    {
        return byFlag;
    }
    *pbySecond = driverapp_rtc_bcd_to_decimal(byTmp);

    return 1;
}

// 配置RTC初始时间
uint8 driverapp_rtc_set_current_datetime(uint8 year, uint8 month, uint8 date, uint8 hour, uint8 minute, uint8 second)
{
    uint8 byInData = 0;
    uint8 byOutData = 0;

    // 年
    byInData = driverapp_rtc_decimal_to_bcd(year);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_YEAR, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_YEAR, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 月
    byInData = driverapp_rtc_decimal_to_bcd(month);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_MONTH, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_MONTH, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 日
    byInData = driverapp_rtc_decimal_to_bcd(date);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_DAY, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_DAY, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 小时
    byInData = driverapp_rtc_decimal_to_bcd(hour);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_HOUR, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_HOUR, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 分
    byInData = driverapp_rtc_decimal_to_bcd(minute);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_MINUTE, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_MINUTE, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    // 秒
    byInData = driverapp_rtc_decimal_to_bcd(second);
    driverapp_rtc_write_data(RTC_REG_ADDRESS_SECOND, &byInData, 1);
    driverapp_rtc_read_data(RTC_REG_ADDRESS_SECOND, &byOutData, 1);
    if (byInData != byOutData)
    {
        return 0;
    }

    return 1;
}

// BCD编码：将十进制数转换为BCD码，原理：十位左移4位后与个位或
uint8 driverapp_rtc_decimal_to_bcd(uint8 decimal)
{
    return ((decimal / 10) << 4) | (decimal % 10);
}

// BCD解码：将BCD码转换为十进制数，原理：取高4位作为十位，低4位作为个位
uint8 driverapp_rtc_bcd_to_decimal(uint8 bcd)
{
    return ((bcd >> 4) * 10) + (bcd & 0x0F);
}