File indexing completed on 2025-05-11 08:24:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <rtems.h>
0012 #include <rtems/rtc.h>
0013 #include <rtems/tod.h>
0014 #include <rtems/libio.h>
0015 #include <rtems/rtems/clockimpl.h>
0016
0017 #include <libchip/rtc.h>
0018
0019
0020
0021
0022 static rtems_device_minor_number RTC_Minor = UINT32_MAX;
0023
0024 static bool RTC_Is_present(void)
0025 {
0026 return RTC_Minor != UINT32_MAX;
0027 }
0028
0029
0030
0031
0032
0033
0034 rtems_device_driver rtc_initialize(
0035 rtems_device_major_number major,
0036 rtems_device_minor_number minor_arg,
0037 void *arg
0038 )
0039 {
0040 rtems_device_minor_number minor;
0041 rtems_status_code status;
0042
0043 for (minor=0; minor < RTC_Count ; minor++) {
0044
0045
0046
0047
0048
0049 if (RTC_Table[minor].deviceProbe && RTC_Table[minor].deviceProbe(minor)) {
0050
0051
0052
0053 RTC_Minor = minor;
0054 break;
0055 }
0056 }
0057
0058 if ( !RTC_Is_present() ) {
0059
0060
0061
0062
0063 return RTEMS_INVALID_NUMBER;
0064 }
0065
0066
0067
0068
0069 status = rtems_io_register_name( RTC_DEVICE_NAME, major, RTC_Minor );
0070 if (status != RTEMS_SUCCESSFUL) {
0071 rtems_fatal_error_occurred(status);
0072 }
0073
0074 RTC_Table[minor].pDeviceFns->deviceInitialize( RTC_Minor );
0075
0076
0077
0078
0079 for ( minor++ ; minor<RTC_Count ; minor++) {
0080
0081
0082
0083
0084
0085 if (RTC_Table[minor].deviceProbe && RTC_Table[minor].deviceProbe(minor)) {
0086 status = rtems_io_register_name(
0087 RTC_Table[minor].sDeviceName,
0088 major,
0089 minor );
0090 if (status != RTEMS_SUCCESSFUL) {
0091 rtems_fatal_error_occurred(status);
0092 }
0093
0094
0095
0096
0097 RTC_Table[minor].pDeviceFns->deviceInitialize(minor);
0098
0099 }
0100 }
0101
0102 setRealTimeToRTEMS();
0103 return RTEMS_SUCCESSFUL;
0104 }
0105
0106 rtems_device_driver rtc_read(
0107 rtems_device_major_number major,
0108 rtems_device_minor_number minor,
0109 void *arg
0110 )
0111 {
0112 int rv = 0;
0113 rtems_libio_rw_args_t *rw = arg;
0114 rtems_time_of_day *tod = (rtems_time_of_day *) rw->buffer;
0115
0116 rw->offset = 0;
0117 rw->bytes_moved = 0;
0118
0119 if (!RTC_Is_present()) {
0120 return RTEMS_NOT_CONFIGURED;
0121 }
0122
0123 if (rw->count != sizeof( rtems_time_of_day)) {
0124 return RTEMS_INVALID_SIZE;
0125 }
0126
0127 rv = RTC_Table [RTC_Minor].pDeviceFns->deviceGetTime(
0128 RTC_Minor,
0129 tod
0130 );
0131 if (rv != 0) {
0132 return RTEMS_IO_ERROR;
0133 }
0134
0135 rw->bytes_moved = rw->count;
0136
0137 return RTEMS_SUCCESSFUL;
0138 }
0139
0140 rtems_device_driver rtc_write(
0141 rtems_device_major_number major,
0142 rtems_device_minor_number minor,
0143 void *arg
0144 )
0145 {
0146 int rv = 0;
0147 rtems_libio_rw_args_t *rw = arg;
0148 const rtems_time_of_day *tod = (const rtems_time_of_day *) rw->buffer;
0149
0150 rw->offset = 0;
0151 rw->bytes_moved = 0;
0152
0153 if (!RTC_Is_present()) {
0154 return RTEMS_NOT_CONFIGURED;
0155 }
0156
0157 if (rw->count != sizeof( rtems_time_of_day)) {
0158 return RTEMS_INVALID_SIZE;
0159 }
0160
0161 rv = RTC_Table [RTC_Minor].pDeviceFns->deviceSetTime(
0162 RTC_Minor,
0163 tod
0164 );
0165 if (rv != 0) {
0166 return RTEMS_IO_ERROR;
0167 }
0168
0169 rw->bytes_moved = rw->count;
0170
0171 return RTEMS_SUCCESSFUL;
0172 }
0173
0174 rtems_device_driver rtc_open(
0175 rtems_device_major_number major,
0176 rtems_device_minor_number minor,
0177 void *arg
0178 )
0179 {
0180 return RTEMS_SUCCESSFUL;
0181 }
0182
0183 rtems_device_driver rtc_close(
0184 rtems_device_major_number major,
0185 rtems_device_minor_number minor,
0186 void *arg
0187 )
0188 {
0189 return RTEMS_SUCCESSFUL;
0190 }
0191
0192 rtems_device_driver rtc_control(
0193 rtems_device_major_number major,
0194 rtems_device_minor_number minor,
0195 void *arg
0196 )
0197 {
0198 return RTEMS_NOT_IMPLEMENTED;
0199 }
0200
0201
0202
0203
0204 void setRealTimeToRTEMS()
0205 {
0206 rtems_time_of_day rtc_tod;
0207
0208 if (!RTC_Is_present())
0209 return;
0210
0211 RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, &rtc_tod);
0212 rtems_clock_set( &rtc_tod );
0213 }
0214
0215
0216
0217
0218
0219
0220 void setRealTimeFromRTEMS(void)
0221 {
0222 rtems_time_of_day rtems_tod;
0223
0224 if (!RTC_Is_present())
0225 return;
0226
0227 rtems_clock_get_tod( &rtems_tod );
0228 RTC_Table[RTC_Minor].pDeviceFns->deviceSetTime(RTC_Minor, &rtems_tod);
0229 }
0230
0231
0232
0233
0234
0235
0236 void getRealTime(
0237 rtems_time_of_day *tod
0238 )
0239 {
0240 if (!RTC_Is_present())
0241 return;
0242
0243 RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, tod);
0244 }
0245
0246
0247
0248
0249
0250
0251 int setRealTime(
0252 const rtems_time_of_day *tod
0253 )
0254 {
0255 if (!RTC_Is_present())
0256 return -1;
0257
0258 if (_TOD_Validate(tod, TOD_ENABLE_TICKS_VALIDATION) != RTEMS_SUCCESSFUL)
0259 return -1;
0260
0261 RTC_Table[RTC_Minor].pDeviceFns->deviceSetTime(RTC_Minor, tod);
0262 return 0;
0263 }
0264
0265
0266
0267
0268
0269
0270
0271 int checkRealTime(void)
0272 {
0273 rtems_time_of_day rtems_tod;
0274 rtems_time_of_day rtc_tod;
0275 uint32_t rtems_time;
0276 uint32_t rtc_time;
0277
0278 if (!RTC_Is_present())
0279 return -1;
0280
0281 rtems_clock_get_tod( &rtems_tod );
0282 RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, &rtc_tod);
0283
0284 rtems_time = _TOD_To_seconds( &rtems_tod );
0285 rtc_time = _TOD_To_seconds( &rtc_tod );
0286
0287 return rtems_time - rtc_time;
0288 }