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, ETH Zurich.
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 Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
15 */
16
17#include <stdio.h>
18#include <barrelfish/barrelfish.h>
19#include <barrelfish_kpi/x86.h>
20#include <dev/lpc_rtc_dev.h>
21#include "rtc.h"
22
23/** \brief This function reads the hardware clock.
24    This function reads the hardware real time clock and fills the
25    passed struct with the read values.
26    \param t pointer to a rtc_time struct
27*/
28
29void rtc_write_cmos(int addr, uint8_t b)
30{
31    lpc_rtc_t rtc;
32    lpc_rtc_initialize(&rtc,0x00);
33    lpc_rtc_ndx_wr(&rtc,addr);
34    lpc_rtc_target_wr(&rtc,b);
35}
36
37void rtc_write_extended(int addr, uint8_t b)
38{
39    lpc_rtc_t rtc;
40    lpc_rtc_initialize(&rtc,0x00);
41    lpc_rtc_endx_wr(&rtc,addr);
42    lpc_rtc_etarget_wr(&rtc,b);
43}
44
45uint8_t rtc_read_cmos(int addr)
46{
47    lpc_rtc_t rtc;
48    lpc_rtc_initialize(&rtc,0x00);
49    lpc_rtc_ndx_wr(&rtc,addr);
50    return lpc_rtc_target_rd(&rtc);
51}
52
53uint8_t rtc_read_extended(int addr, uint8_t b)
54{
55    lpc_rtc_t rtc;
56    lpc_rtc_initialize(&rtc,0x00);
57    lpc_rtc_endx_wr(&rtc,addr);
58    return lpc_rtc_etarget_rd(&rtc);
59}
60
61static inline uint8_t _rtc_read( lpc_rtc_t *rtc, uint8_t _r)
62{
63    lpc_rtc_ndx_wr(rtc,_r);
64    return lpc_rtc_target_rd(rtc);
65}
66
67
68void rtc_read(struct rtc_time *t)
69{
70    uint8_t sec, min, hr;
71
72    lpc_rtc_t rtc;
73    lpc_rtc_initialize(&rtc,0x00);
74
75    // read hour
76    hr = _rtc_read(&rtc, lpc_rtc_hours );
77
78    // read minutes
79    min = _rtc_read(&rtc, lpc_rtc_minutes );
80
81    // read seconds
82    sec = _rtc_read(&rtc, lpc_rtc_seconds );
83
84    // Convert in the case of BCD hours
85    lpc_rtc_ndx_wr(&rtc, lpc_rtc_regb);
86    if ( lpc_rtc_regb_rd(&rtc).dm ) {
87        t->hr = hr;
88        t->min = min;
89        t->sec = sec;
90    } else {
91        t->hr = (hr / 16) * 10 + hr % 16;
92        t->min = (min / 16) * 10 + min % 16;
93        t->sec = (sec / 16) * 10 + sec % 16;
94    }
95}
96
97uint8_t rtc_read_secs(void)
98{
99    lpc_rtc_t rtc;
100    lpc_rtc_initialize(&rtc, 0x00);
101    return _rtc_read(&rtc, lpc_rtc_seconds);
102}
103
104/** \brief Print current time.
105    This function prints the given time
106    \param t pointer to a rtc_time struct
107*/
108
109void rtc_print(struct rtc_time *t)
110{
111    printf("%02hhu:%02hhu:%02hhu\n", t->hr, t->min, t->sec);
112}
113