source: rtems/c/src/lib/libcpu/bfin/clock/rtc.c @ 61b5aec

4.104.115
Last change on this file since 61b5aec was 61b5aec, checked in by Ralf Corsepius <ralf.corsepius@…>, on 10/20/09 at 12:54:46

2009-10-20 Ralf Corsépius <ralf.corsepius@…>

  • clock/rtc.c: Add initializer (Silence warning).
  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*  Real Time Clock Driver for Blackfin
2 *
3 *  Copyright (c) 2006 by Atos Automacao Industrial Ltda.
4 *             written by Alain Schaefer <alain.schaefer@easc.ch>
5 *                    and Antonio Giovanini <antonio@atos.com.br>
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13 
14
15#include <rtems.h>
16#include "tod.h"
17#include <rtems/rtc.h>
18#include <rtems/libio.h>
19#include <bsp.h>
20#include <libcpu/rtcRegs.h>
21
22/* The following are inside RTEMS -- we are violating visibility!!!
23 * Perhaps an API could be defined to get days since 1 Jan.
24 */
25extern const uint16_t   _TOD_Days_to_date[2][13];
26
27/*
28 *  Prototypes and routines used below
29 */
30int Leap_years_until_now (int year);
31
32void Init_RTC(void)
33{
34  *((uint16_t*)RTC_PREN)    = RTC_PREN_PREN; /* Enable Prescaler */
35}
36
37/*
38 *  Read time from RTEMS' clock manager and set it to RTC
39 */
40
41void setRealTimeFromRTEMS (void)
42{
43  rtems_time_of_day time_buffer;
44  rtems_status_code status;
45 
46  status = rtems_clock_get( RTEMS_CLOCK_GET_TOD, &time_buffer ); 
47  if (status == RTEMS_SUCCESSFUL){
48    setRealTime(&time_buffer);
49  }
50}
51
52/*
53 *  Read real time from RTC and set it to RTEMS' clock manager
54 */
55
56void setRealTimeToRTEMS (void)
57{
58  rtems_time_of_day time_buffer;
59 
60  getRealTime(&time_buffer); 
61  rtems_clock_set( &time_buffer ); 
62}
63
64 /*
65  * Set the RTC time
66  */
67int setRealTime(
68  const rtems_time_of_day *tod
69)
70{
71  uint32_t days;
72  rtems_time_of_day tod_temp;
73 
74  tod_temp = *tod;
75 
76  days = (tod_temp.year - TOD_BASE_YEAR) * 365 + \
77          _TOD_Days_to_date[0][tod_temp.month] + tod_temp.day - 1;
78  if (tod_temp.month < 3)
79    days +=  Leap_years_until_now (tod_temp.year - 1);
80  else
81    days +=  Leap_years_until_now (tod_temp.year);
82 
83  *((uint32_t volatile *)RTC_STAT) = (days << RTC_STAT_DAYS_SHIFT)|
84                                     (tod_temp.hour << RTC_STAT_HOURS_SHIFT)|
85                                     (tod_temp.minute << RTC_STAT_MINUTES_SHIFT)|
86                                     tod_temp.second;
87
88  return 0;
89}
90
91 /*
92  *  Get the time from the RTC.
93  */
94
95void getRealTime(
96  rtems_time_of_day *tod
97)
98{
99  uint32_t days, rtc_reg;
100  rtems_time_of_day tod_temp = { 0, 0, 0 };
101  int n, Leap_year;
102 
103  rtc_reg = *((uint32_t volatile *)RTC_STAT);
104 
105  days = (rtc_reg >> RTC_STAT_DAYS_SHIFT) + 1;
106 
107  /* finding year */
108  tod_temp.year = days/365 + TOD_BASE_YEAR;
109  if (days%365 >  Leap_years_until_now (tod_temp.year - 1)) {
110    days = (days%365) -  Leap_years_until_now (tod_temp.year - 1);
111  } else {
112    tod_temp.year--;
113    days = (days%365) + 365 -  Leap_years_until_now (tod_temp.year - 1);
114  }
115
116  /* finding month and day */ 
117  Leap_year = (((!(tod_temp.year%4)) && (tod_temp.year%100)) ||
118              (!(tod_temp.year%400)))?1:0;
119  for (n=1; n<=12; n++) {
120    if (days <= _TOD_Days_to_date[Leap_year][n+1]) {
121      tod_temp.month = n;
122      tod_temp.day = days - _TOD_Days_to_date[Leap_year][n];
123      break;
124    }
125  }
126
127  tod_temp.hour  = (rtc_reg & RTC_STAT_HOURS_MASK) >> RTC_STAT_HOURS_SHIFT;
128  tod_temp.minute  = (rtc_reg & RTC_STAT_MINUTES_MASK) >> RTC_STAT_MINUTES_SHIFT;
129  tod_temp.second  = (rtc_reg & RTC_STAT_SECONDS_MASK);
130  tod_temp.ticks = 0;
131  *tod = tod_temp;
132}
133
134/*
135 *  Return the difference between RTC and RTEMS' clock manager time in minutes.
136 *  If the difference is greater than 1 day, this returns 9999.
137 */
138
139int checkRealTime (void)
140{
141  rtems_time_of_day rtems_tod;
142  rtems_time_of_day rtc_tod;
143  uint32_t   rtems_time;
144  uint32_t   rtc_time;
145
146  rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );
147  getRealTime ( &rtc_tod );
148
149  rtems_time = _TOD_To_seconds( &rtems_tod );
150  rtc_time = _TOD_To_seconds( &rtc_tod );
151
152  return rtems_time - rtc_time;
153}
154
155int Leap_years_until_now (int year)
156{
157  return ((year/4 - year/100 + year/400) -
158         ((TOD_BASE_YEAR - 1)/4 - (TOD_BASE_YEAR - 1)/100 +
159          (TOD_BASE_YEAR - 1)/400));
160}
161
162rtems_device_driver rtc_initialize(
163  rtems_device_major_number  major,
164  rtems_device_minor_number  minor_arg,
165  void                      *arg
166)
167{
168  rtems_status_code          status;
169
170  /*
171   *  Register and initialize the primary RTC's
172   */
173
174  status = rtems_io_register_name( RTC_DEVICE_NAME, major, 0 );
175  if (status != RTEMS_SUCCESSFUL) {
176    rtems_fatal_error_occurred(status);
177  }
178
179  Init_RTC();
180
181  setRealTimeToRTEMS();
182  return RTEMS_SUCCESSFUL;
183}
184
185rtems_device_driver rtc_read(
186  rtems_device_major_number  major,
187  rtems_device_minor_number  minor,
188  void *arg
189)
190{
191  rtems_libio_rw_args_t *rw = arg;
192  rtems_time_of_day *tod = (rtems_time_of_day *) rw->buffer;
193
194  rw->offset = 0;
195  rw->bytes_moved = 0;
196
197  if (rw->count != sizeof( rtems_time_of_day)) {
198    return RTEMS_INVALID_SIZE;
199  }
200
201  getRealTime( tod);
202
203  rw->bytes_moved = rw->count;
204
205  return RTEMS_SUCCESSFUL;
206}
207
208rtems_device_driver rtc_write(
209  rtems_device_major_number  major,
210  rtems_device_minor_number  minor,
211  void *arg
212)
213{
214  int rv = 0;
215  rtems_libio_rw_args_t *rw = arg;
216  const rtems_time_of_day *tod = (const rtems_time_of_day *) rw->buffer;
217
218  rw->offset = 0;
219  rw->bytes_moved = 0;
220
221  if (rw->count != sizeof( rtems_time_of_day)) {
222    return RTEMS_INVALID_SIZE;
223  }
224
225  rv = setRealTime( tod);
226  if (rv != 0) {
227    return RTEMS_IO_ERROR;
228  }
229
230  rw->bytes_moved = rw->count;
231
232  return RTEMS_SUCCESSFUL;
233}
234
235rtems_device_driver rtc_open(
236  rtems_device_major_number major,
237  rtems_device_minor_number minor,
238  void *arg
239)
240{
241  return RTEMS_SUCCESSFUL;
242}
243
244rtems_device_driver rtc_close(
245  rtems_device_major_number major,
246  rtems_device_minor_number minor,
247  void *arg
248)
249{
250  return RTEMS_SUCCESSFUL;
251}
252
253rtems_device_driver rtc_control(
254  rtems_device_major_number major,
255  rtems_device_minor_number minor,
256  void *arg
257)
258{
259  return RTEMS_NOT_IMPLEMENTED;
260}
Note: See TracBrowser for help on using the repository browser.