rtc.c 4.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * File      : rtc.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006, RT-Thread Development Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://openlab.rt-thread.com/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2009-04-26     yi.qiu       first version
 */

qiuyiuestc's avatar
qiuyiuestc 已提交
15 16 17
#include <rtthread.h>
#include <time.h>
#include <s3c24x0.h>
G
gary.li.wenchao.4 已提交
18
#include "rtc.h"
19 20 21 22 23


/**
 * This function get rtc time
 */
G
gary.li.wenchao.4 已提交
24
void rt_hw_rtc_get(struct rtc_time *ti)
25 26 27 28
{
	rt_uint8_t sec, min, hour, mday, wday, mon, year;

	/* enable access to RTC registers */
G
gary.li.wenchao.4 已提交
29
	RTCCON |= RTC_ENABLE;
30 31

	/* read RTC registers */
B
bernard.xiong 已提交
32
	do
33
	{
G
gary.li.wenchao.4 已提交
34 35
		sec 	= BCDSEC;
		min 	= BCDMIN;
qiuyiuestc's avatar
qiuyiuestc 已提交
36 37 38 39 40
		hour 	= BCDHOUR;
		mday	= BCDDATE;
		wday 	= BCDDAY;
		mon 	= BCDMON;
		year 	= BCDYEAR;
41 42 43
        } while (sec != BCDSEC);

	/* disable access to RTC registers */
qiuyiuestc's avatar
qiuyiuestc 已提交
44 45 46 47 48 49 50 51 52 53 54
	RTCCON &= ~0x01;

	ti->tm_sec  	= BCD2BIN(sec  & 0x7F);
	ti->tm_min  	= BCD2BIN(min  & 0x7F);
	ti->tm_hour 	= BCD2BIN(hour & 0x3F);
	ti->tm_mday 	= BCD2BIN(mday & 0x3F);
	ti->tm_mon  	= BCD2BIN(mon & 0x1F);
	ti->tm_year 	= BCD2BIN(year);
	ti->tm_wday 	= BCD2BIN(wday & 0x07);
	ti->tm_yday 	= 0;
	ti->tm_isdst 	= 0;
55 56 57 58 59
}

/**
 * This function set rtc time
 */
G
gary.li.wenchao.4 已提交
60
void rt_hw_rtc_set(struct rtc_time *ti)
61 62 63
{
	rt_uint8_t sec, min, hour, mday, wday, mon, year;

qiuyiuestc's avatar
qiuyiuestc 已提交
64 65 66 67 68
	year 	= BIN2BCD(ti->tm_year);
	mon 	= BIN2BCD(ti->tm_mon);
	wday 	= BIN2BCD(ti->tm_wday);
	mday 	= BIN2BCD(ti->tm_mday);
	hour 	= BIN2BCD(ti->tm_hour);
G
gary.li.wenchao.4 已提交
69 70
	min 	= BIN2BCD(ti->tm_min);
	sec 	= BIN2BCD(ti->tm_sec);
71 72

	/* enable access to RTC registers */
qiuyiuestc's avatar
qiuyiuestc 已提交
73
	RTCCON |= 0x01;
74 75

	/* write RTC registers */
qiuyiuestc's avatar
qiuyiuestc 已提交
76 77 78 79 80
	BCDSEC 		= sec;
	BCDMIN 		= min;
	BCDHOUR 	= hour;
	BCDDATE 	= mday;
	BCDDAY 		= wday;
G
gary.li.wenchao.4 已提交
81
	BCDMON 		= mon;
qiuyiuestc's avatar
qiuyiuestc 已提交
82
	BCDYEAR 	= year;
83 84

	/* disable access to RTC registers */
qiuyiuestc's avatar
qiuyiuestc 已提交
85
	RTCCON &= ~0x01;
86 87 88 89 90 91 92 93 94 95 96
}

/**
 * This function reset rtc
 */
void rt_hw_rtc_reset (void)
{
	RTCCON = (RTCCON & ~0x06) | 0x08;
	RTCCON &= ~(0x08|0x01);
}

qiuyiuestc's avatar
qiuyiuestc 已提交
97 98 99 100 101 102 103 104
static struct rt_device rtc;
static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag)
{
	return RT_EOK;
}

static rt_size_t rt_rtc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
G
gary.li.wenchao.4 已提交
105
	return RT_EOK;
qiuyiuestc's avatar
qiuyiuestc 已提交
106 107 108 109
}

static rt_err_t rt_rtc_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
G
gary.li.wenchao.4 已提交
110
	struct rtc_time* time;
qiuyiuestc's avatar
qiuyiuestc 已提交
111 112
	RT_ASSERT(dev != RT_NULL);

G
gary.li.wenchao.4 已提交
113
	time = (struct rtc_time*)args;
qiuyiuestc's avatar
qiuyiuestc 已提交
114 115 116 117
	switch (cmd)
	{
	case RT_DEVICE_CTRL_RTC_GET_TIME:
		/* read device */
G
gary.li.wenchao.4 已提交
118
		rt_hw_rtc_get(time);
qiuyiuestc's avatar
qiuyiuestc 已提交
119 120 121 122
		break;

	case RT_DEVICE_CTRL_RTC_SET_TIME:
		/* write device */
G
gary.li.wenchao.4 已提交
123
		rt_hw_rtc_set(time);
qiuyiuestc's avatar
qiuyiuestc 已提交
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
		break;
	}

	return RT_EOK;
}

void rt_hw_rtc_init(void)
{
	rtc.type	= RT_Device_Class_RTC;

	/* register rtc device */
	rtc.init 	= RT_NULL;
	rtc.open 	= rt_rtc_open;
	rtc.close	= RT_NULL;
	rtc.read 	= rt_rtc_read;
	rtc.write	= RT_NULL;
	rtc.control = rt_rtc_control;
	
	/* no private */
	rtc.private = RT_NULL;
	
	rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);

}

time_t time(time_t* t)
{
	rt_device_t device;
	struct tm ti;
	time_t time;
	
	device = rt_device_find("rtc");
	if (device != RT_NULL)
	{
		rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &ti);
		if (t != RT_NULL) 
		{
			time = mktime(&ti);
			*t = time;
		}	
	}
	
	return time;
}

169 170
#ifdef RT_USING_FINSH
#include <finsh.h>
qiuyiuestc's avatar
qiuyiuestc 已提交
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
void set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day)
{
	struct tm ti;
	rt_device_t device;
		
	device = rt_device_find("rtc");
	if (device != RT_NULL)
	{
		rt_rtc_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &ti);
		ti.tm_year 	= year - 1900;
		ti.tm_mon 	= month - 1;
		ti.tm_mday 	= day;
		rt_rtc_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &ti);
	}
}
G
gary.li.wenchao.4 已提交
186
FINSH_FUNCTION_EXPORT(set_date, set date(year, month, day))
qiuyiuestc's avatar
qiuyiuestc 已提交
187 188 189 190 191 192 193 194 195 196 197

void set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second)
{
	struct tm ti;
	rt_device_t device;
		
	device = rt_device_find("rtc");
	if (device != RT_NULL)
	{
		rt_rtc_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &ti);
		ti.tm_hour	= hour;
G
gary.li.wenchao.4 已提交
198
		ti.tm_min	= minute;
qiuyiuestc's avatar
qiuyiuestc 已提交
199 200 201 202
		ti.tm_sec 	= second;
		rt_rtc_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &ti);
	}
}
G
gary.li.wenchao.4 已提交
203
FINSH_FUNCTION_EXPORT(set_time, set time(hour, minute, second))
qiuyiuestc's avatar
qiuyiuestc 已提交
204

G
gary.li.wenchao.4 已提交
205
void list_date(void)
qiuyiuestc's avatar
qiuyiuestc 已提交
206 207 208 209 210 211
{
	time_t now;
	
	time(&now);
	rt_kprintf("%s\n", ctime(&now));
}
G
gary.li.wenchao.4 已提交
212
FINSH_FUNCTION_EXPORT(list_date, list date)
qiuyiuestc's avatar
qiuyiuestc 已提交
213 214
#endif