source: rtems/c/src/lib/libcpu/bfin/clock/rtc.c @ 24868ecb

4.115
Last change on this file since 24868ecb was 24868ecb, checked in by Joel Sherrill <joel.sherrill@…>, on 03/14/15 at 16:00:20

libcpu/bfin/clock/rtc.c: Do not use rtems_clock_get()

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