summaryrefslogtreecommitdiff
path: root/firmware/drivers/fat.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/fat.c')
-rw-r--r--firmware/drivers/fat.c99
1 files changed, 54 insertions, 45 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index e319669e97..578397cbe6 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -1001,70 +1001,79 @@ static void fat_time(unsigned short* date,
1001#else 1001#else
1002 /* non-RTC version returns an increment from the supplied time, or a 1002 /* non-RTC version returns an increment from the supplied time, or a
1003 * fixed standard time/date if no time given as input */ 1003 * fixed standard time/date if no time given as input */
1004
1005/* Macros to convert a 2-digit string to a decimal constant.
1006 (YEAR), MONTH and DAY are set by the date command, which outputs
1007 DAY as 00..31 and MONTH as 01..12. The leading zero would lead to
1008 misinterpretation as an octal constant. */
1009#define S100(x) 1 ## x
1010#define C2DIG2DEC(x) (S100(x)-100)
1011/* The actual build date, as FAT date constant */
1012#define BUILD_DATE_FAT (((YEAR - 1980) << 9) \
1013 | (C2DIG2DEC(MONTH) << 5) \
1014 | C2DIG2DEC(DAY))
1015
1016 bool date_forced = false;
1004 bool next_day = false; 1017 bool next_day = false;
1018 unsigned time2 = 0; /* double time, for CRTTIME with 1s precision */
1005 1019
1020 if (date && *date < BUILD_DATE_FAT)
1021 {
1022 *date = BUILD_DATE_FAT;
1023 date_forced = true;
1024 }
1025
1006 if (time) 1026 if (time)
1007 { 1027 {
1008 if (0 == *time) 1028 time2 = *time << 1;
1029 if (time2 == 0 || date_forced)
1009 { 1030 {
1010 /* set to 00:15:00 */ 1031 time2 = (11 < 6) | 11; /* set to 00:11:11 */
1011 *time = (15 << 5);
1012 } 1032 }
1013 else 1033 else
1014 { 1034 {
1015 unsigned short mins = (*time >> 5) & 0x003F; 1035 unsigned mins = (time2 >> 6) & 0x3f;
1016 unsigned short hours = (*time >> 11) & 0x001F; 1036 unsigned hours = (time2 >> 12) & 0x1f;
1017 if ((mins += 10) >= 60) 1037
1018 { 1038 mins = 11 * ((mins/11) + 1); /* advance to next multiple of 11 */
1019 mins = 0; 1039 if (mins > 59)
1020 hours++;
1021 }
1022 if ((++hours) >= 24)
1023 { 1040 {
1024 hours = hours - 24; 1041 mins = 11; /* 00 would be a bad marker */
1025 next_day = true; 1042 if (++hours > 23)
1043 {
1044 hours = 0;
1045 next_day = true;
1046 }
1026 } 1047 }
1027 *time = (hours << 11) | (mins << 5); 1048 time2 = (hours << 12) | (mins << 6) | mins; /* secs = mins */
1028 } 1049 }
1050 *time = time2 >> 1;
1029 } 1051 }
1052
1053 if (tenth)
1054 *tenth = (time2 & 1) * 100;
1030 1055
1031 if (date) 1056 if (date && next_day)
1032 { 1057 {
1033 if (0 == *date) 1058 static const unsigned char daysinmonth[] =
1034 { 1059 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
1035/* Macros to convert a 2-digit string to a decimal constant. 1060 unsigned day = *date & 0x1f;
1036 (YEAR), MONTH and DAY are set by the date command, which outputs 1061 unsigned month = (*date >> 5) & 0x0f;
1037 DAY as 00..31 and MONTH as 01..12. The leading zero would lead to 1062 unsigned year = (*date >> 9) & 0x7f;
1038 misinterpretation as an octal constant. */ 1063
1039#define S100(x) 1 ## x 1064 /* simplification: ignore leap years */
1040#define C2DIG2DEC(x) (S100(x)-100) 1065 if (++day > daysinmonth[month-1])
1041 /* set to build date */
1042 *date = ((YEAR - 1980) << 9) | (C2DIG2DEC(MONTH) << 5)
1043 | C2DIG2DEC(DAY);
1044 }
1045 else
1046 { 1066 {
1047 unsigned short day = *date & 0x001F; 1067 day = 1;
1048 unsigned short month = (*date >> 5) & 0x000F; 1068 if (++month > 12)
1049 unsigned short year = (*date >> 9) & 0x007F;
1050 if (next_day)
1051 { 1069 {
1052 /* do a very simple day increment - never go above 28 days */ 1070 month = 1;
1053 if (++day > 28) 1071 year++;
1054 {
1055 day = 1;
1056 if (++month > 12)
1057 {
1058 month = 1;
1059 year++;
1060 }
1061 }
1062 *date = (year << 9) | (month << 5) | day;
1063 } 1072 }
1064 } 1073 }
1074 *date = (year << 9) | (month << 5) | day;
1065 } 1075 }
1066 if (tenth) 1076
1067 *tenth = 0;
1068#endif /* CONFIG_RTC */ 1077#endif /* CONFIG_RTC */
1069} 1078}
1070 1079