1/**
2 * \file
3 * \brief Simple RTC hardware clock access.
4 *
5 * This file implements a simple driver for the hardware real time clock.
6 */
7
8/*
9 * Copyright (c) 2007, 2008, 2010, ETH Z��rich.
10 * All rights reserved.
11 *
12 * This file is distributed under the terms in the attached LICENSE file.
13 * If you do not find this file, copies can be found by writing to:
14 * ETH Z��rich D-INFK, Haldeneggsteig 4, CH-8092 Z��rich. Attn: NetOS Group.
15 */
16
17#include <kernel.h>
18#include <stdio.h>
19#include <arch/x86/rtc.h>
20#include <dev/lpc_rtc_dev.h>
21
22static lpc_rtc_t rtc;
23
24/** \brief This function reads the hardware clock.
25    This function reads the hardware real time clock and fills the
26    passed struct with the read values.
27    \param t pointer to a rtc_time struct
28*/
29
30void rtc_write_cmos(int addr, uint8_t b)
31{
32    lpc_rtc_ndx_wr(&rtc,addr);
33    lpc_rtc_target_wr(&rtc,b);
34}
35
36void rtc_write_extended(int addr, uint8_t b)
37{
38    lpc_rtc_endx_wr(&rtc,addr);
39    lpc_rtc_etarget_wr(&rtc,b);
40}
41
42uint8_t rtc_read_cmos(int addr)
43{
44    lpc_rtc_ndx_wr(&rtc,addr);
45    return lpc_rtc_target_rd(&rtc);
46}
47
48uint8_t rtc_read_extended(int addr, uint8_t b)
49{
50    lpc_rtc_endx_wr(&rtc,addr);
51    return lpc_rtc_etarget_rd(&rtc);
52}
53
54static inline uint8_t _rtc_read( lpc_rtc_t *rt, uint8_t _r)
55{
56    lpc_rtc_ndx_wr(rt,_r);
57    return lpc_rtc_target_rd(rt);
58}
59
60
61void rtc_read(struct rtc_time *t)
62{
63    uint8_t sec, min, hr;
64
65    // read hour
66    hr = _rtc_read(&rtc, lpc_rtc_hours );
67
68    // read minutes
69    min = _rtc_read(&rtc, lpc_rtc_minutes );
70
71    // read seconds
72    sec = _rtc_read(&rtc, lpc_rtc_seconds );
73
74    // Convert in the case of BCD hours
75    lpc_rtc_ndx_wr(&rtc, lpc_rtc_regb);
76    if ( lpc_rtc_regb_dm_rdf(&rtc) ) {
77        t->hr = hr;
78        t->min = min;
79        t->sec = sec;
80    } else {
81        t->hr = (hr / 16) * 10 + hr % 16;
82        t->min = (min / 16) * 10 + min % 16;
83        t->sec = (sec / 16) * 10 + sec % 16;
84    }
85}
86
87uint8_t rtc_read_secs(void)
88{
89    while(_rtc_read(&rtc, lpc_rtc_rega) & 128);
90    return _rtc_read(&rtc, lpc_rtc_seconds);
91}
92
93void rtc_init(void)
94{
95    lpc_rtc_initialize(&rtc, 0x00);
96
97    // Set RTC to binary mode (not BCD), no interrupts
98    /* rtc_write_cmos(0xb, (1 << 1) | (1 << 2)); */
99}
100
101/** \brief Print current time.
102    This function prints the given time
103    \param t pointer to a rtc_time struct
104*/
105void rtc_print(struct rtc_time *t)
106{
107    printf("%02hhu:%02hhu:%02hhu\n", t->hr, t->min, t->sec);
108}
109