source: rtems/c/src/lib/libbsp/m68k/mcf5206elite/tod/ds1307.c @ c2e6a059

4.104.115
Last change on this file since c2e6a059 was c2e6a059, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/08/09 at 13:12:45

(ds1307_set_time): Fix broken prototype.

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 * This file interfaces with the real-time clock found in a
3 * Dallas Semiconductor DS1307/DS1308 serial real-time clock chip.
4 * This RTC have I2C bus interface. BSP have to provide I2C bus primitives
5 * to make this driver working. getRegister and setRegister primitives is
6 * not used here to avoid multiple transactions over I2C bus (each transaction
7 * require significant time and error when date/time information red may
8 * occurs). ulControlPort contains I2C bus number; ulDataPort contains
9 * RTC I2C device address.
10 *
11 * Year 2000 Note:
12 *
13 * This chip only uses a two digit field to store the year. This code
14 * uses the RTEMS Epoch as a pivot year. This lets us map the two digit
15 * year field as follows:
16 *
17 *    + two digit years 00-87 are mapped to 2000-2087
18 *    + two digit years 88-99 are mapped to 1988-1999
19 *
20 * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
21 * Author: Victor V. Vengerov <vvv@oktet.ru>
22 *
23 * The license and distribution terms for this file may be
24 * found in the file LICENSE in this distribution or at
25 *
26 * http://www.rtems.com/license/LICENSE.
27 *
28 * @(#) $Id$
29 */
30
31#include <rtems.h>
32#include <libchip/rtc.h>
33#include <string.h>
34#include "ds1307.h"
35#include "i2c.h"
36
37/* Convert from/to Binary-Coded Decimal representation */
38#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
39#define To_BCD( _x )   ((((_x) / 10) << 4) + ((_x) % 10))
40
41/* ds1307_initialize --
42 *     Initialize DS1307 real-time clock chip. If RTC is halted, this
43 *     function resume counting.
44 *
45 * PARAMETERS:
46 *     minor -- minor RTC device number
47 */
48void
49ds1307_initialize(int minor)
50{
51    i2c_message_status status;
52    int try;
53    uint8_t         sec;
54    i2c_bus_number bus;
55    i2c_address addr;
56
57    bus = RTC_Table[minor].ulCtrlPort1;
58    addr = RTC_Table[minor].ulDataPort;
59
60    /* Read SECONDS register */
61    try = 0;
62    do {
63        status = i2c_wbrd(bus, addr, 0, &sec, sizeof(sec));
64        try++;
65    } while ((status != I2C_SUCCESSFUL) && (try < 15));
66
67    /* If clock is halted, reset and start the clock */
68    if ((sec & DS1307_SECOND_HALT) != 0)
69    {
70        uint8_t         start[8];
71        memset(start, 0, sizeof(start));
72        start[0] = DS1307_SECOND;
73        try = 0;
74        do {
75            status = i2c_write(bus, addr, start, 2);
76        } while ((status != I2C_SUCCESSFUL) && (try < 15));
77    }
78}
79
80/* ds1307_get_time --
81 *     read current time from DS1307 real-time clock chip and convert it
82 *     to the rtems_time_of_day structure.
83 *
84 * PARAMETERS:
85 *     minor -- minor RTC device number
86 *     time -- place to put return value (date and time)
87 *
88 * RETURNS:
89 *     0, if time obtained successfully
90 *     -1, if error occured
91 */
92int
93ds1307_get_time(int minor, rtems_time_of_day *time)
94{
95    i2c_bus_number bus;
96    i2c_address addr;
97    uint8_t         info[8];
98    uint32_t         v1, v2;
99    i2c_message_status status;
100    int try;
101
102    if (time == NULL)
103        return -1;
104
105    bus = RTC_Table[minor].ulCtrlPort1;
106    addr = RTC_Table[minor].ulDataPort;
107
108    memset(time, 0, sizeof(rtems_time_of_day));
109    try = 0;
110    do {
111        status = i2c_wbrd(bus, addr, 0, info, sizeof(info));
112        try++;
113    } while ((status != I2C_SUCCESSFUL) && (try < 10));
114
115    if (status != I2C_SUCCESSFUL)
116    {
117        return -1;
118    }
119
120    v1 = info[DS1307_YEAR];
121    v2 = From_BCD(v1);
122    if (v2 < 88)
123        time->year = 2000 + v2;
124    else
125        time->year = 1900 + v2;
126
127    v1 = info[DS1307_MONTH] & ~0xE0;
128    time->month = From_BCD(v1);
129
130    v1 = info[DS1307_DAY] & ~0xC0;
131    time->day = From_BCD(v1);
132
133    v1 = info[DS1307_HOUR];
134    if (v1 & DS1307_HOUR_12)
135    {
136        v2 = v1 & ~0xE0;
137        if (v1 & DS1307_HOUR_PM)
138        {
139            time->hour = From_BCD(v2) + 12;
140        }
141        else
142        {
143            time->hour = From_BCD(v2);
144        }
145    }
146    else
147    {
148        v2 = v1 & ~0xC0;
149        time->hour = From_BCD(v2);
150    }
151
152    v1 = info[DS1307_MINUTE] & ~0x80;
153    time->minute = From_BCD(v1);
154
155    v1 = info[DS1307_SECOND];
156    v2 = v1 & ~0x80;
157    time->second = From_BCD(v2);
158
159    return 0;
160}
161
162/* ds1307_set_time --
163 *     set time to the DS1307 real-time clock chip
164 *
165 * PARAMETERS:
166 *     minor -- minor RTC device number
167 *     time -- new date and time to be written to DS1307
168 *
169 * RETURNS:
170 *     0, if time obtained successfully
171 *     -1, if error occured
172 */
173int
174ds1307_set_time(int minor, const rtems_time_of_day *time)
175{
176    i2c_bus_number bus;
177    i2c_address addr;
178    uint8_t         info[8];
179    i2c_message_status status;
180    int try;
181
182    if (time == NULL)
183        return -1;
184
185    bus = RTC_Table[minor].ulCtrlPort1;
186    addr = RTC_Table[minor].ulDataPort;
187
188    if (time->year >= 2088)
189        rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);
190
191    info[0] = DS1307_SECOND;
192    info[1 + DS1307_YEAR] = To_BCD(time->year % 100);
193    info[1 + DS1307_MONTH] = To_BCD(time->month);
194    info[1 + DS1307_DAY] = To_BCD(time->day);
195    info[1 + DS1307_HOUR] = To_BCD(time->hour);
196    info[1 + DS1307_MINUTE] = To_BCD(time->minute);
197    info[1 + DS1307_SECOND] = To_BCD(time->second);
198    info[1 + DS1307_DAY_OF_WEEK] = 1; /* Do not set day of week */
199
200    try = 0;
201    do {
202        status = i2c_write(bus, addr, info, 8);
203        try++;
204    } while ((status != I2C_SUCCESSFUL) && (try < 10));
205
206    if (status != I2C_SUCCESSFUL)
207        return -1;
208    else
209        return 0;
210}
211
212/* Driver function table */
213
214rtc_fns ds1307_fns = {
215    ds1307_initialize,
216    ds1307_get_time,
217    ds1307_set_time
218};
Note: See TracBrowser for help on using the repository browser.