File indexing completed on 2025-05-11 08:23:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <rtems.h>
0017 #include <rtems/tod.h>
0018 #include <rtems/rtc.h>
0019 #include <rtems/libio.h>
0020 #include <bsp.h>
0021 #include <libcpu/rtcRegs.h>
0022 #include <rtems/score/todimpl.h>
0023 #include <rtems/rtems/clockimpl.h>
0024
0025
0026
0027
0028 int Leap_years_until_now (int year);
0029
0030 void Init_RTC(void)
0031 {
0032 *((uint16_t*)RTC_PREN) = RTC_PREN_PREN;
0033 }
0034
0035
0036
0037
0038 void setRealTimeFromRTEMS (void)
0039 {
0040 rtems_time_of_day time_buffer;
0041 rtems_status_code status;
0042
0043 status = rtems_clock_get_tod( &time_buffer );
0044 if (status == RTEMS_SUCCESSFUL){
0045 setRealTime(&time_buffer);
0046 }
0047 }
0048
0049
0050
0051
0052 void setRealTimeToRTEMS (void)
0053 {
0054 rtems_time_of_day time_buffer;
0055
0056 getRealTime(&time_buffer);
0057 rtems_clock_set( &time_buffer );
0058 }
0059
0060
0061
0062
0063 int setRealTime(
0064 const rtems_time_of_day *tod
0065 )
0066 {
0067 uint32_t days;
0068 rtems_time_of_day tod_temp;
0069
0070 tod_temp = *tod;
0071
0072 days = (tod_temp.year - TOD_BASE_YEAR) * 365 + \
0073 _TOD_Days_to_date[1][tod_temp.month] + tod_temp.day - 1;
0074 if (tod_temp.month < 3)
0075 days += Leap_years_until_now (tod_temp.year - 1);
0076 else
0077 days += Leap_years_until_now (tod_temp.year);
0078
0079 *((uint32_t volatile *)RTC_STAT) = (days << RTC_STAT_DAYS_SHIFT)|
0080 (tod_temp.hour << RTC_STAT_HOURS_SHIFT)|
0081 (tod_temp.minute << RTC_STAT_MINUTES_SHIFT)|
0082 tod_temp.second;
0083
0084 return 0;
0085 }
0086
0087
0088
0089
0090 void getRealTime(
0091 rtems_time_of_day *tod
0092 )
0093 {
0094 uint32_t days, rtc_reg;
0095 rtems_time_of_day tod_temp = { 0, 0, 0 };
0096 int n, Leap_year;
0097
0098 rtc_reg = *((uint32_t volatile *)RTC_STAT);
0099
0100 days = (rtc_reg >> RTC_STAT_DAYS_SHIFT) + 1;
0101
0102
0103 tod_temp.year = days/365 + TOD_BASE_YEAR;
0104 if (days%365 > Leap_years_until_now (tod_temp.year - 1)) {
0105 days = (days%365) - Leap_years_until_now (tod_temp.year - 1);
0106 } else {
0107 tod_temp.year--;
0108 days = (days%365) + 365 - Leap_years_until_now (tod_temp.year - 1);
0109 }
0110
0111
0112 Leap_year = (((!(tod_temp.year%4)) && (tod_temp.year%100)) ||
0113 (!(tod_temp.year%400)))?0:1;
0114 for (n=1; n<=12; n++) {
0115 if (days <= _TOD_Days_to_date[Leap_year][n+1]) {
0116 tod_temp.month = n;
0117 tod_temp.day = days - _TOD_Days_to_date[Leap_year][n];
0118 break;
0119 }
0120 }
0121
0122 tod_temp.hour = (rtc_reg & RTC_STAT_HOURS_MASK) >> RTC_STAT_HOURS_SHIFT;
0123 tod_temp.minute = (rtc_reg & RTC_STAT_MINUTES_MASK) >> RTC_STAT_MINUTES_SHIFT;
0124 tod_temp.second = (rtc_reg & RTC_STAT_SECONDS_MASK);
0125 tod_temp.ticks = 0;
0126 *tod = tod_temp;
0127 }
0128
0129
0130
0131
0132
0133 int checkRealTime (void)
0134 {
0135 rtems_time_of_day rtems_tod;
0136 rtems_time_of_day rtc_tod;
0137 uint32_t rtems_time;
0138 uint32_t rtc_time;
0139
0140 (void) rtems_clock_get_tod( &rtems_tod );
0141 getRealTime ( &rtc_tod );
0142
0143 rtems_time = _TOD_To_seconds( &rtems_tod );
0144 rtc_time = _TOD_To_seconds( &rtc_tod );
0145
0146 return rtems_time - rtc_time;
0147 }
0148
0149 int Leap_years_until_now (int year)
0150 {
0151 return ((year/4 - year/100 + year/400) -
0152 ((TOD_BASE_YEAR - 1)/4 - (TOD_BASE_YEAR - 1)/100 +
0153 (TOD_BASE_YEAR - 1)/400));
0154 }
0155
0156 rtems_device_driver rtc_initialize(
0157 rtems_device_major_number major,
0158 rtems_device_minor_number minor_arg,
0159 void *arg
0160 )
0161 {
0162 rtems_status_code status;
0163
0164
0165
0166
0167
0168 status = rtems_io_register_name( RTC_DEVICE_NAME, major, 0 );
0169 if (status != RTEMS_SUCCESSFUL) {
0170 rtems_fatal_error_occurred(status);
0171 }
0172
0173 Init_RTC();
0174
0175 setRealTimeToRTEMS();
0176 return RTEMS_SUCCESSFUL;
0177 }
0178
0179 rtems_device_driver rtc_read(
0180 rtems_device_major_number major,
0181 rtems_device_minor_number minor,
0182 void *arg
0183 )
0184 {
0185 rtems_libio_rw_args_t *rw = arg;
0186 rtems_time_of_day *tod = (rtems_time_of_day *) rw->buffer;
0187
0188 rw->offset = 0;
0189 rw->bytes_moved = 0;
0190
0191 if (rw->count != sizeof( rtems_time_of_day)) {
0192 return RTEMS_INVALID_SIZE;
0193 }
0194
0195 getRealTime( tod);
0196
0197 rw->bytes_moved = rw->count;
0198
0199 return RTEMS_SUCCESSFUL;
0200 }
0201
0202 rtems_device_driver rtc_write(
0203 rtems_device_major_number major,
0204 rtems_device_minor_number minor,
0205 void *arg
0206 )
0207 {
0208 int rv = 0;
0209 rtems_libio_rw_args_t *rw = arg;
0210 const rtems_time_of_day *tod = (const rtems_time_of_day *) rw->buffer;
0211
0212 rw->offset = 0;
0213 rw->bytes_moved = 0;
0214
0215 if (rw->count != sizeof( rtems_time_of_day)) {
0216 return RTEMS_INVALID_SIZE;
0217 }
0218
0219 rv = setRealTime( tod);
0220 if (rv != 0) {
0221 return RTEMS_IO_ERROR;
0222 }
0223
0224 rw->bytes_moved = rw->count;
0225
0226 return RTEMS_SUCCESSFUL;
0227 }
0228
0229 rtems_device_driver rtc_open(
0230 rtems_device_major_number major,
0231 rtems_device_minor_number minor,
0232 void *arg
0233 )
0234 {
0235 return RTEMS_SUCCESSFUL;
0236 }
0237
0238 rtems_device_driver rtc_close(
0239 rtems_device_major_number major,
0240 rtems_device_minor_number minor,
0241 void *arg
0242 )
0243 {
0244 return RTEMS_SUCCESSFUL;
0245 }
0246
0247 rtems_device_driver rtc_control(
0248 rtems_device_major_number major,
0249 rtems_device_minor_number minor,
0250 void *arg
0251 )
0252 {
0253 return RTEMS_NOT_IMPLEMENTED;
0254 }