summaryrefslogtreecommitdiff
path: root/bsp/nrf5x/libraries/drivers/drv_rtc.c
blob: 366be3ccd6437ec3dcb9a3fd4797f9dd26b37503 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Copyright (c) 2006-2025, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date         Author        Notes
 * 2020-09-08   Chenyingchun  first version
 */

#include "board.h"
#include <rtthread.h>
#include <rtdevice.h>
#include <sys/time.h>
#include <nrfx_rtc.h>
#include <nrfx_clock.h>

#ifdef BSP_USING_ONCHIP_RTC

#define LOG_TAG             "drv.rtc"
#define DBG_LVL              DBG_LOG
#include <rtdbg.h>

/* 2018-01-30 14:44:50 = RTC_TIME_INIT(2018, 1, 30, 14, 44, 50)  */
#define RTC_TIME_INIT(year, month, day, hour, minute, second)        \
    {.tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day, .tm_hour = hour, .tm_min = minute, .tm_sec = second}

#ifndef ONCHIP_RTC_TIME_DEFAULT
#define ONCHIP_RTC_TIME_DEFAULT                    RTC_TIME_INIT(2018, 1, 1, 0, 0 ,0)
#endif

#ifndef RTC_INSTANCE_ID
#define RTC_INSTANCE_ID (2)
#endif

#define TICK_FREQUENCE_HZ        (RT_TICK_PER_SECOND)     /* RTC tick frequence, in HZ */

static struct rt_rtc_device rtc;
static time_t init_time;
static uint32_t tick = 0;

static void rtc_callback(nrfx_rtc_int_type_t int_type)
{
    static uint32_t count = 0;

    if (int_type == NRFX_RTC_INT_TICK)
    {
       count++;
       if((count % TICK_FREQUENCE_HZ) == 0)
       {
            tick++;
       }
    }
}

static rt_err_t rt_rtc_config(struct rt_device *dev)
{
    #define SYSTICK_CLOCK_HZ    (32768UL)
    #define RTC_PRESCALER       ((uint32_t) (NRFX_ROUNDED_DIV(SYSTICK_CLOCK_HZ, TICK_FREQUENCE_HZ) - 1))

    const nrfx_rtc_t rtc_instance = NRFX_RTC_INSTANCE(RTC_INSTANCE_ID);
    nrf_clock_lf_src_set(NRF_CLOCK, (nrf_clock_lfclk_t)NRFX_CLOCK_CONFIG_LF_SRC);
    nrfx_clock_lfclk_start();

    /* Initialize RTC instance */
    nrfx_rtc_config_t config = NRFX_RTC_DEFAULT_CONFIG;
    config.prescaler = RTC_PRESCALER;

    nrfx_rtc_init(&rtc_instance, &config, rtc_callback);

    nrfx_rtc_tick_enable(&rtc_instance, true);

    /* Power on RTC instance */
    nrfx_rtc_enable(&rtc_instance);

    return RT_EOK;
}

static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args)
{
    time_t *time;
    RT_ASSERT(dev != RT_NULL);

    switch (cmd)
    {
        case RT_DEVICE_CTRL_RTC_GET_TIME:
        {
            time = (time_t *) args;
            *time = init_time + tick;
            break;
        }
        case RT_DEVICE_CTRL_RTC_SET_TIME:
        {
            time = (time_t *) args;
            init_time = *time - tick;
            break;
        }
    }
    return RT_EOK;
}


#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops rtc_ops =
{
    RT_NULL,
    RT_NULL,
    RT_NULL,
    RT_NULL,
    RT_NULL,
    rt_rtc_control
};
#endif


int rt_hw_rtc_init(void)
{
    rt_err_t result;

    result = rt_hw_rtc_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR,RT_NULL);

    if (result != RT_EOK)
    {
        LOG_E("rtc register err code: %d", result);
        return result;
    }
    LOG_D("rtc init success");
    return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_rtc_init);

#endif /* BSP_USING_ONCHIP_RTC */