source: rtems/c/src/lib/libbsp/shared/tod.c @ b2ed712

5
Last change on this file since b2ed712 was 0057e38f, checked in by Sebastian Huber <sebastian.huber@…>, on 07/04/16 at 09:06:53

libchip: Simplify RTC driver

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 *  Real Time Clock Driver Wrapper for Libchip
3 */
4
5/*
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.org/license/LICENSE.
9 */
10
11#include <rtems.h>
12#include <rtems/rtc.h>
13#include <rtems/tod.h>
14#include <rtems/libio.h>
15
16#include <libchip/rtc.h>
17
18/*
19 *  Configuration Information
20 */
21static rtems_device_minor_number RTC_Minor = UINT32_MAX;
22
23static bool RTC_Is_present(void)
24{
25  return RTC_Minor != UINT32_MAX;
26}
27
28/*
29 *  rtc_initialize
30 *
31 *  Initialize the RTC driver
32 */
33rtems_device_driver rtc_initialize(
34  rtems_device_major_number  major,
35  rtems_device_minor_number  minor_arg,
36  void                      *arg
37)
38{
39  rtems_device_minor_number minor;
40  rtems_status_code status;
41
42  for (minor=0; minor < RTC_Count ; minor++) {
43    /*
44     * First perform the configuration dependent probe, then the
45     * device dependent probe
46     */
47
48    if (RTC_Table[minor].deviceProbe && RTC_Table[minor].deviceProbe(minor)) {
49      /*
50       * Use this device as the primary RTC
51       */
52      RTC_Minor = minor;
53      break;
54    }
55  }
56
57  if ( !RTC_Is_present() ) {
58    /*
59     * Failed to find an RTC -- this is not a fatal error.
60     */
61
62    return RTEMS_INVALID_NUMBER;
63  }
64
65  /*
66   *  Register and initialize the primary RTC's
67   */
68  status = rtems_io_register_name( RTC_DEVICE_NAME, major, RTC_Minor );
69  if (status != RTEMS_SUCCESSFUL) {
70    rtems_fatal_error_occurred(status);
71  }
72
73  RTC_Table[minor].pDeviceFns->deviceInitialize( RTC_Minor );
74
75  /*
76   *  Now initialize any secondary RTC's
77   */
78  for ( minor++ ; minor<RTC_Count ; minor++) {
79    /*
80     * First perform the configuration dependent probe, then the
81     * device dependent probe
82     */
83
84    if (RTC_Table[minor].deviceProbe && RTC_Table[minor].deviceProbe(minor)) {
85      status = rtems_io_register_name(
86        RTC_Table[minor].sDeviceName,
87        major,
88        minor );
89      if (status != RTEMS_SUCCESSFUL) {
90        rtems_fatal_error_occurred(status);
91      }
92
93      /*
94       * Initialize the hardware device.
95       */
96      RTC_Table[minor].pDeviceFns->deviceInitialize(minor);
97
98    }
99  }
100
101  setRealTimeToRTEMS();
102  return RTEMS_SUCCESSFUL;
103}
104
105rtems_device_driver rtc_read(
106  rtems_device_major_number  major,
107  rtems_device_minor_number  minor,
108  void *arg
109)
110{
111  int rv = 0;
112  rtems_libio_rw_args_t *rw = arg;
113  rtems_time_of_day *tod = (rtems_time_of_day *) rw->buffer;
114
115  rw->offset = 0;
116  rw->bytes_moved = 0;
117
118  if (!RTC_Is_present()) {
119    return RTEMS_NOT_CONFIGURED;
120  }
121
122  if (rw->count != sizeof( rtems_time_of_day)) {
123    return RTEMS_INVALID_SIZE;
124  }
125
126  rv = RTC_Table [RTC_Minor].pDeviceFns->deviceGetTime(
127    RTC_Minor,
128    tod
129  );
130  if (rv != 0) {
131    return RTEMS_IO_ERROR;
132  }
133
134  rw->bytes_moved = rw->count;
135
136  return RTEMS_SUCCESSFUL;
137}
138
139rtems_device_driver rtc_write(
140  rtems_device_major_number  major,
141  rtems_device_minor_number  minor,
142  void *arg
143)
144{
145  int rv = 0;
146  rtems_libio_rw_args_t *rw = arg;
147  const rtems_time_of_day *tod = (const rtems_time_of_day *) rw->buffer;
148
149  rw->offset = 0;
150  rw->bytes_moved = 0;
151
152  if (!RTC_Is_present()) {
153    return RTEMS_NOT_CONFIGURED;
154  }
155
156  if (rw->count != sizeof( rtems_time_of_day)) {
157    return RTEMS_INVALID_SIZE;
158  }
159
160  rv = RTC_Table [RTC_Minor].pDeviceFns->deviceSetTime(
161    RTC_Minor,
162    tod
163  );
164  if (rv != 0) {
165    return RTEMS_IO_ERROR;
166  }
167
168  rw->bytes_moved = rw->count;
169
170  return RTEMS_SUCCESSFUL;
171}
172
173rtems_device_driver rtc_open(
174  rtems_device_major_number major,
175  rtems_device_minor_number minor,
176  void *arg
177)
178{
179  return RTEMS_SUCCESSFUL;
180}
181
182rtems_device_driver rtc_close(
183  rtems_device_major_number major,
184  rtems_device_minor_number minor,
185  void *arg
186)
187{
188  return RTEMS_SUCCESSFUL;
189}
190
191rtems_device_driver rtc_control(
192  rtems_device_major_number major,
193  rtems_device_minor_number minor,
194  void *arg
195)
196{
197  return RTEMS_NOT_IMPLEMENTED;
198}
199
200/*
201 *  This routine copies the time from the real time clock to RTEMS
202 */
203void setRealTimeToRTEMS()
204{
205  rtems_time_of_day rtc_tod;
206
207  if (!RTC_Is_present())
208    return;
209
210  RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, &rtc_tod);
211  rtems_clock_set( &rtc_tod );
212}
213
214/*
215 *  setRealTimeFromRTEMS
216 *
217 *  This routine copies the time from RTEMS to the real time clock
218 */
219void setRealTimeFromRTEMS(void)
220{
221  rtems_time_of_day rtems_tod;
222
223  if (!RTC_Is_present())
224    return;
225
226  rtems_clock_get_tod( &rtems_tod );
227  RTC_Table[RTC_Minor].pDeviceFns->deviceSetTime(RTC_Minor, &rtems_tod);
228}
229
230/*
231 *  getRealTime
232 *
233 *  This routine reads the current time from the RTC.
234 */
235void getRealTime(
236  rtems_time_of_day *tod
237)
238{
239  if (!RTC_Is_present())
240    return;
241
242  RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, tod);
243}
244
245/*
246 *  setRealTime
247 *
248 *  This routine sets the RTC.
249 */
250int setRealTime(
251  const rtems_time_of_day *tod
252)
253{
254  if (!RTC_Is_present())
255    return -1;
256
257  if ( !_TOD_Validate(tod) )
258    return -1;
259
260  RTC_Table[RTC_Minor].pDeviceFns->deviceSetTime(RTC_Minor, tod);
261  return 0;
262}
263
264/*
265 *  checkRealTime
266 *
267 *  This routine reads the returns the variance betweent the real time and
268 *  RTEMS time.
269 */
270int checkRealTime(void)
271{
272  rtems_time_of_day rtems_tod;
273  rtems_time_of_day rtc_tod;
274  uint32_t   rtems_time;
275  uint32_t   rtc_time;
276
277  if (!RTC_Is_present())
278    return -1;
279
280  rtems_clock_get_tod( &rtems_tod );
281  RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, &rtc_tod);
282
283  rtems_time = _TOD_To_seconds( &rtems_tod );
284  rtc_time = _TOD_To_seconds( &rtc_tod );
285
286  return rtems_time - rtc_time;
287}
Note: See TracBrowser for help on using the repository browser.