File indexing completed on 2025-05-11 08:23:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <rtems.h>
0031 #include <libchip/rtc.h>
0032 #include <string.h>
0033 #include "ds1307.h"
0034 #include "i2c.h"
0035
0036
0037 #define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
0038 #define To_BCD( _x ) ((((_x) / 10) << 4) + ((_x) % 10))
0039
0040
0041
0042
0043
0044
0045
0046
0047 static void ds1307_initialize(int minor)
0048 {
0049 i2c_message_status status;
0050 int try;
0051 uint8_t sec;
0052 i2c_bus_number bus;
0053 i2c_address addr;
0054
0055 bus = RTC_Table[minor].ulCtrlPort1;
0056 addr = RTC_Table[minor].ulDataPort;
0057
0058
0059 try = 0;
0060 do {
0061 status = i2c_wbrd(bus, addr, 0, &sec, sizeof(sec));
0062 try++;
0063 } while ((status != I2C_SUCCESSFUL) && (try < 15));
0064
0065
0066 if ((sec & DS1307_SECOND_HALT) != 0) {
0067 uint8_t start[8];
0068 memset(start, 0, sizeof(start));
0069 start[0] = DS1307_SECOND;
0070 try = 0;
0071 do {
0072 status = i2c_write(bus, addr, start, 2);
0073 } while ((status != I2C_SUCCESSFUL) && (try < 15));
0074 }
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 static int ds1307_get_time(int minor, rtems_time_of_day *time)
0090 {
0091 i2c_bus_number bus;
0092 i2c_address addr;
0093 uint8_t info[8];
0094 uint32_t v1, v2;
0095 i2c_message_status status;
0096 int try;
0097
0098 if (time == NULL)
0099 return -1;
0100
0101 bus = RTC_Table[minor].ulCtrlPort1;
0102 addr = RTC_Table[minor].ulDataPort;
0103
0104 memset(time, 0, sizeof(rtems_time_of_day));
0105 try = 0;
0106 do {
0107 status = i2c_wbrd(bus, addr, 0, info, sizeof(info));
0108 try++;
0109 } while ((status != I2C_SUCCESSFUL) && (try < 10));
0110
0111 if (status != I2C_SUCCESSFUL) {
0112 return -1;
0113 }
0114
0115 v1 = info[DS1307_YEAR];
0116 v2 = From_BCD(v1);
0117 if (v2 < 88)
0118 time->year = 2000 + v2;
0119 else
0120 time->year = 1900 + v2;
0121
0122 v1 = info[DS1307_MONTH] & ~0xE0;
0123 time->month = From_BCD(v1);
0124
0125 v1 = info[DS1307_DAY] & ~0xC0;
0126 time->day = From_BCD(v1);
0127
0128 v1 = info[DS1307_HOUR];
0129 if (v1 & DS1307_HOUR_12) {
0130 v2 = v1 & ~0xE0;
0131 if (v1 & DS1307_HOUR_PM) {
0132 time->hour = From_BCD(v2) + 12;
0133 } else {
0134 time->hour = From_BCD(v2);
0135 }
0136 } else {
0137 v2 = v1 & ~0xC0;
0138 time->hour = From_BCD(v2);
0139 }
0140
0141 v1 = info[DS1307_MINUTE] & ~0x80;
0142 time->minute = From_BCD(v1);
0143
0144 v1 = info[DS1307_SECOND];
0145 v2 = v1 & ~0x80;
0146 time->second = From_BCD(v2);
0147
0148 return 0;
0149 }
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 static int ds1307_set_time(int minor, const rtems_time_of_day *time)
0163 {
0164 i2c_bus_number bus;
0165 i2c_address addr;
0166 uint8_t info[8];
0167 i2c_message_status status;
0168 int try;
0169
0170 if (time == NULL)
0171 return -1;
0172
0173 bus = RTC_Table[minor].ulCtrlPort1;
0174 addr = RTC_Table[minor].ulDataPort;
0175
0176 if (time->year >= 2088)
0177 rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);
0178
0179 info[0] = DS1307_SECOND;
0180 info[1 + DS1307_YEAR] = To_BCD(time->year % 100);
0181 info[1 + DS1307_MONTH] = To_BCD(time->month);
0182 info[1 + DS1307_DAY] = To_BCD(time->day);
0183 info[1 + DS1307_HOUR] = To_BCD(time->hour);
0184 info[1 + DS1307_MINUTE] = To_BCD(time->minute);
0185 info[1 + DS1307_SECOND] = To_BCD(time->second);
0186 info[1 + DS1307_DAY_OF_WEEK] = 1;
0187
0188 try = 0;
0189 do {
0190 status = i2c_write(bus, addr, info, 8);
0191 try++;
0192 } while ((status != I2C_SUCCESSFUL) && (try < 10));
0193
0194 if (status != I2C_SUCCESSFUL)
0195 return -1;
0196 else
0197 return 0;
0198 }
0199
0200
0201
0202 rtc_fns ds1307_fns = {
0203 ds1307_initialize,
0204 ds1307_get_time,
0205 ds1307_set_time
0206 };