<commit_before>/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2012-10-27     heyuanjie87       first version.
 * 2013-05-17     aozima            initial alarm event & mutex in system init.
 * 2020-10-15     zhangsz           add alarm flags hour minute second.
 */

#include <rtthread.h>
#include <rtdevice.h>

#define RT_RTC_YEARS_MAX         137
#define RT_ALARM_DELAY             2
#define RT_ALARM_STATE_INITED   0x02
#define RT_ALARM_STATE_START    0x01
#define RT_ALARM_STATE_STOP     0x00

#if (defined(RT_USING_RTC) && defined(RT_USING_ALARM))
static struct rt_alarm_container _container;

rt_inline rt_uint32_t alarm_mkdaysec(struct tm *time)
{
    rt_uint32_t sec;

    sec = time->tm_sec;
    sec += time->tm_min * 60;
    sec += time->tm_hour * 3600;

    return (sec);
}

static rt_err_t alarm_set(struct rt_alarm *alarm)
{
    rt_device_t device;
    struct rt_rtc_wkalarm wkalarm;
    rt_err_t ret;

    device = rt_device_find("rtc");
    if (device == RT_NULL)
    {
        return (RT_ERROR);
    }
    if (alarm->flag & RT_ALARM_STATE_START)
        wkalarm.enable = RT_TRUE;
    else
        wkalarm.enable = RT_FALSE;

    wkalarm.tm_sec = alarm->wktime.tm_sec;
    wkalarm.tm_min = alarm->wktime.tm_min;
    wkalarm.tm_hour = alarm->wktime.tm_hour;

    ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_ALARM, &wkalarm);
    if ((ret == RT_EOK) && wkalarm.enable)
    {
        ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_ALARM, &wkalarm);
        if (ret == RT_EOK)
        {
            /*
              some RTC device like RX8025,it's alarms precision is 1 minute.
              in this case,low level RTC driver should set wkalarm->tm_sec to 0.
            */
            alarm->wktime.tm_sec = wkalarm.tm_sec;
            alarm->wktime.tm_min = wkalarm.tm_min;
            alarm->wktime.tm_hour = wkalarm.tm_hour;
        }
    }

    return (ret);
}

static void alarm_wakeup(struct rt_alarm *alarm, struct tm *now)
{
    rt_uint32_t sec_alarm, sec_now;
    rt_bool_t wakeup = RT_FALSE;
    time_t timestamp;

    sec_alarm = alarm_mkdaysec(&alarm->wktime);
    sec_now = alarm_mkdaysec(now);

    if (alarm->flag & RT_ALARM_STATE_START)
    {
        switch (alarm->flag & 0xFF00)
        {
        case RT_ALARM_ONESHOT:
        {
            sec_alarm = mktime(&alarm->wktime);
            sec_now = mktime(now);
            if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm))
            {
                /* stop alarm */
                alarm->flag &= ~RT_ALARM_STATE_START;
                alarm_set(alarm);
                wakeup = RT_TRUE;
            }
        }
        break;
        case RT_ALARM_SECOND:
        {
            alarm->wktime.tm_hour = now->tm_hour;
            alarm->wktime.tm_min = now->tm_min;
            alarm->wktime.tm_sec = alarm->wktime.tm_sec + 1;
            if (alarm->wktime.tm_sec > 59)
            {
                alarm->wktime.tm_sec = 0;
                alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
                if (alarm->wktime.tm_min > 59)
                {
                    alarm->wktime.tm_min = 0;
                    alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
                    if (alarm->wktime.tm_hour > 23)
                    {
                        alarm->wktime.tm_hour = 0;
                    }
                }
            }
            wakeup = RT_TRUE;
        }
        break;
        case RT_ALARM_MINUTE:
        {
            alarm->wktime.tm_hour = now->tm_hour;
            if (alarm->wktime.tm_sec == now->tm_sec)
            {
                alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
                if (alarm->wktime.tm_min > 59)
                {
                    alarm->wktime.tm_min = 0;
                    alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
                    if (alarm->wktime.tm_hour > 23)
                    {
                        alarm->wktime.tm_hour = 0;
                    }
                }
                wakeup = RT_TRUE;
            }
        }
        break;
        case RT_ALARM_HOUR:
        {
            if ((alarm->wktime.tm_min == now->tm_min) &&
                (alarm->wktime.tm_sec == now->tm_sec))
            {
                alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;<commit_msg>[rtc.alarm][fix]fix alarm when update datetime<commit_after>/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2012-10-27     heyuanjie87       first version.
 * 2013-05-17     aozima            initial alarm event & mutex in system init.
 * 2020-10-15     zhangsz           add alarm flags hour minute second.
 * 2020-11-09     zhangsz           fix alarm set when modify rtc time.
 */

#include <rtthread.h>
#include <rtdevice.h>

#define RT_RTC_YEARS_MAX         137
#define RT_ALARM_DELAY             2
#define RT_ALARM_STATE_INITED   0x02
#define RT_ALARM_STATE_START    0x01
#define RT_ALARM_STATE_STOP     0x00

#if (defined(RT_USING_RTC) && defined(RT_USING_ALARM))
static struct rt_alarm_container _container;

rt_inline rt_uint32_t alarm_mkdaysec(struct tm *time)
{
    rt_uint32_t sec;

    sec = time->tm_sec;
    sec += time->tm_min * 60;
    sec += time->tm_hour * 3600;

    return (sec);
}

static rt_err_t alarm_set(struct rt_alarm *alarm)
{
    rt_device_t device;
    struct rt_rtc_wkalarm wkalarm;
    rt_err_t ret;

    device = rt_device_find("rtc");
    if (device == RT_NULL)
    {
        return (RT_ERROR);
    }
    if (alarm->flag & RT_ALARM_STATE_START)
        wkalarm.enable = RT_TRUE;
    else
        wkalarm.enable = RT_FALSE;

    wkalarm.tm_sec = alarm->wktime.tm_sec;
    wkalarm.tm_min = alarm->wktime.tm_min;
    wkalarm.tm_hour = alarm->wktime.tm_hour;

    ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_ALARM, &wkalarm);
    if ((ret == RT_EOK) && wkalarm.enable)
    {
        ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_ALARM, &wkalarm);
        if (ret == RT_EOK)
        {
            /*
              some RTC device like RX8025,it's alarms precision is 1 minute.
              in this case,low level RTC driver should set wkalarm->tm_sec to 0.
            */
            alarm->wktime.tm_sec = wkalarm.tm_sec;
            alarm->wktime.tm_min = wkalarm.tm_min;
            alarm->wktime.tm_hour = wkalarm.tm_hour;
        }
    }

    return (ret);
}

static void alarm_wakeup(struct rt_alarm *alarm, struct tm *now)
{
    rt_uint32_t sec_alarm, sec_now;
    rt_bool_t wakeup = RT_FALSE;
    time_t timestamp;

    sec_alarm = alarm_mkdaysec(&alarm->wktime);
    sec_now = alarm_mkdaysec(now);

    if (alarm->flag & RT_ALARM_STATE_START)
    {
        switch (alarm->flag & 0xFF00)
        {
        case RT_ALARM_ONESHOT:
        {
            sec_alarm = mktime(&alarm->wktime);
            sec_now = mktime(now);
            if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm))
            {
                /* stop alarm */
                alarm->flag &= ~RT_ALARM_STATE_START;
                alarm_set(alarm);
                wakeup = RT_TRUE;
            }
        }
        break;
        case RT_ALARM_SECOND:
        {
            alarm->wktime.tm_hour = now->tm_hour;
            alarm->wktime.tm_min = now->tm_min;
            alarm->wktime.tm_sec = now->tm_sec + 1;
            if (alarm->wktime.tm_sec > 59)
            {
                alarm->wktime.tm_sec = 0;
                alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
                if (alarm->wktime.tm_min > 59)
                {
                    alarm->wktime.tm_min = 0;
                    alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
                    if (alarm->wktime.tm_hour > 23)
                    {
                        alarm->wktime.tm_hour = 0;
                    }
                }
            }
            wakeup = RT_TRUE;
        }
        break;
        case RT_ALARM_MINUTE:
        {
            alarm->wktime.tm_hour = now->tm_hour;
            if (alarm->wktime.tm_sec == now->tm_sec)
            {
                alarm->wktime.tm_min = now->tm_min + 1;
                if (alarm->wktime.tm_min > 59)
                {
                    alarm->wktime.tm_min = 0;
                    alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
                    if (alarm->wktime.tm_hour > 23)
                    {
                        alarm->wktime.tm_hour = 0;
                    }
                }
                wakeup = RT_TRUE;
            }
        }
        break;
        case RT_ALARM_HOUR:
        {
            if ((alarm->wktime.tm_min == now->tm_min) &&
                (alarm->wktime.tm_sec == now->tm_sec))
            {
                alarm->wktime.tm_hour = now->tm_hour + 1;
{'fraction_non_alphanumeric': 0.10547486033519553, 'fraction_numerical': 0.021229050279329607, 'mean_word_length': 1.5713875323182993, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 119, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5191574', 'n_tokens_mistral': 3300, 'n_tokens_neox': 3048, 'n_words': 552}