From 7ddf0d673dbb0dbcb6b534db92da5797b9c22ba6 Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Tue, 20 Apr 2004 10:23:57 +0000 Subject: Reworked the time get/set functions git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4522 a1c6a512-1295-4272-9138-f99709370657 --- apps/settings.c | 108 +++++++++++++++++++++++------------------- apps/settings.h | 3 +- apps/settings_menu.c | 71 +++++++-------------------- firmware/common/timefuncs.c | 60 +++++++++++++++++++++++ firmware/include/timefuncs.h | 21 ++------ uisimulator/common/stubs.c | 9 +--- uisimulator/win32/Makefile | 6 ++- uisimulator/win32/timefuncs.h | 3 ++ uisimulator/x11/Makefile | 5 +- uisimulator/x11/timefuncs.h | 3 ++ 10 files changed, 158 insertions(+), 131 deletions(-) diff --git a/apps/settings.c b/apps/settings.c index 8a93617d64..b84ef52205 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -17,7 +17,6 @@ * KIND, either express or implied. * ****************************************************************************/ - #include #include "config.h" #include "kernel.h" @@ -47,6 +46,7 @@ #include "errno.h" #include "system.h" #include "misc.h" +#include "timefuncs.h" #ifdef HAVE_LCD_BITMAP #include "icons.h" #include "font.h" @@ -1963,17 +1963,33 @@ bool set_option(char* string, void* variable, enum optiontype type, #ifdef HAVE_LCD_BITMAP /* little helper function for voice output */ -static void say_time(int cursorpos, int timedate[]) +static void say_time(int cursorpos, struct tm *tm) { const int unit[] = { UNIT_HOUR, UNIT_MIN, UNIT_SEC, 0, 0, 0 }; - int value = timedate[cursorpos]; + int value = 0; if (!global_settings.talk_menu) return; - if (cursorpos == 3) /* year */ - value += 2000; - + switch(cursorpos) + { + case 0: + value = tm->tm_hour; + break; + case 1: + value = tm->tm_min; + break; + case 2: + value = tm->tm_sec; + break; + case 3: + value = tm->tm_year + 1900; + break; + case 5: + value = tm->tm_mday; + break; + } + if (cursorpos == 4) /* month */ talk_id(LANG_MONTH_JANUARY + value - 1, false); else @@ -1984,7 +2000,7 @@ static void say_time(int cursorpos, int timedate[]) #define INDEX_X 0 #define INDEX_Y 1 #define INDEX_WIDTH 2 -bool set_time(char* string, int timedate[]) +bool set_time_screen(char* string, struct tm *tm) { bool done = false; int button; @@ -2024,6 +2040,7 @@ bool set_time(char* string, int timedate[]) int monthname_len = 0, dayname_len = 0; + int *valptr = NULL; #ifdef HAVE_LCD_BITMAP if(global_settings.statusbar) @@ -2036,27 +2053,27 @@ bool set_time(char* string, int timedate[]) while ( !done ) { /* calculate the number of days in febuary */ - realyear = timedate[3] + 2000; + realyear = tm->tm_year + 1900; if((realyear % 4 == 0 && !(realyear % 100 == 0)) || realyear % 400 == 0) daysinmonth[1] = 29; else daysinmonth[1] = 28; /* fix day if month or year changed */ - if (timedate[5] > daysinmonth[timedate[4] - 1]) - timedate[5] = daysinmonth[timedate[4] - 1]; + if (tm->tm_mday > daysinmonth[tm->tm_mon]) + tm->tm_mday = daysinmonth[tm->tm_mon]; /* calculate day of week */ julianday = 0; - for(i = 0; i < timedate[4] - 1; i++) { + for(i = 0; i < tm->tm_mon; i++) { julianday += daysinmonth[i]; } - julianday += timedate[5]; - timedate[6] = (realyear + julianday + (realyear - 1) / 4 - + julianday += tm->tm_mday; + tm->tm_wday = (realyear + julianday + (realyear - 1) / 4 - (realyear - 1) / 100 + (realyear - 1) / 400 + 7 - 1) % 7; snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d ", - timedate[0], timedate[1], timedate[2]); + tm->tm_hour, tm->tm_min, tm->tm_sec); lcd_puts(0, 1, buffer); /* recalculate the positions and offsets */ @@ -2091,17 +2108,17 @@ bool set_time(char* string, int timedate[]) lcd_getstringsize(buffer, &width, &prev_line_height); - snprintf(buffer, sizeof(buffer), "%s 20%02d %s %02d ", - str(dayname[timedate[6]]), timedate[3], - str(monthname[timedate[4] - 1]), timedate[5]); + snprintf(buffer, sizeof(buffer), "%s %04d %s %02d ", + str(dayname[tm->tm_wday]), tm->tm_year+1900, + str(monthname[tm->tm_mon]), tm->tm_mday); lcd_puts(0, 2, buffer); /* recalculate the positions and offsets */ lcd_getstringsize(buffer, &width, &line_height); /* store these 2 to prevent _repeated_ strlen calls */ - monthname_len = strlen(str(monthname[timedate[4] - 1])); - dayname_len = strlen(str(dayname[timedate[6]])); + monthname_len = strlen(str(monthname[tm->tm_mon])); + dayname_len = strlen(str(dayname[tm->tm_wday])); /* weekday */ strncpy(reffub, buffer, dayname_len); @@ -2155,26 +2172,35 @@ bool set_time(char* string, int timedate[]) case 0: /* hour */ min = 0; steps = 24; + valptr = &tm->tm_hour; break; case 1: /* minute */ + min = 0; + steps = 60; + valptr = &tm->tm_min; + break; case 2: /* second */ min = 0; steps = 60; + valptr = &tm->tm_sec; break; case 3: /* year */ - min = 0; - steps = 100; + min = 1; + steps = 200; + valptr = &tm->tm_year; break; case 4: /* month */ - min = 1; + min = 0; steps = 12; + valptr = &tm->tm_mon; break; case 5: /* day */ min = 1; - steps = daysinmonth[timedate[4] - 1]; + steps = daysinmonth[tm->tm_mon]; + valptr = &tm->tm_mday; break; } - say_time(cursorpos, timedate); + say_time(cursorpos, tm); } button = button_get_w_tmo(HZ/2); @@ -2187,43 +2213,27 @@ bool set_time(char* string, int timedate[]) break; case BUTTON_UP: case BUTTON_UP | BUTTON_REPEAT: - timedate[cursorpos] = (timedate[cursorpos] + steps - min + 1) % + *valptr = (*valptr + steps - min + 1) % steps + min; - if(timedate[cursorpos] == 0) - timedate[cursorpos] += min; - say_time(cursorpos, timedate); + if(*valptr == 0) + *valptr = min; + say_time(cursorpos, tm); break; case BUTTON_DOWN: case BUTTON_DOWN | BUTTON_REPEAT: - timedate[cursorpos]=(timedate[cursorpos]+steps - min - 1) % + *valptr = (*valptr + steps - min - 1) % steps + min; - if(timedate[cursorpos] == 0) - timedate[cursorpos] += min; - say_time(cursorpos, timedate); + if(*valptr == 0) + *valptr = min; + say_time(cursorpos, tm); break; case BUTTON_ON: done = true; - if (timedate[6] == 0) /* rtc needs 1 .. 7 */ - timedate[6] = 7; break; case BUTTON_OFF: done = true; - timedate[0] = -1; + tm->tm_year = -1; break; -#ifdef HAVE_RECORDER_KEYPAD - case BUTTON_F3: -#ifdef HAVE_LCD_BITMAP - global_settings.statusbar = !global_settings.statusbar; - settings_save(); - if(global_settings.statusbar) - lcd_setmargins(0, STATUSBAR_HEIGHT); - else - lcd_setmargins(0, 0); - lcd_clear_display(); - lcd_puts_scroll(0, 0, string); -#endif - break; -#endif case SYS_USB_CONNECTED: usb_screen(); diff --git a/apps/settings.h b/apps/settings.h index 0bf67b474b..8d602f17ac 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -23,6 +23,7 @@ #include #include "config.h" #include "file.h" +#include "timefuncs.h" #define ROCKBOX_DIR "/.rockbox" #define FONT_DIR "/fonts" @@ -237,7 +238,7 @@ bool set_option(char* string, void* variable, enum optiontype type, struct opt_items* options, int numoptions, void (*function)(int)); bool set_int(char* string, char* unit, int voice_unit, int* variable, void (*function)(int), int step, int min, int max ); -bool set_time(char* string, int timedate[]); +bool set_time_screen(char* string, struct tm *tm); int read_line(int fd, char* buffer, int buffer_size); void set_file(char* filename, char* setting, int maxlen); diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 10d3665b97..7150dd239d 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -21,6 +21,7 @@ #include #include +#include #include "lcd.h" #include "menu.h" @@ -41,6 +42,7 @@ #include "tree.h" #include "screens.h" #include "talk.h" +#include "timefuncs.h" #ifdef HAVE_LCD_BITMAP #include "peakmeter.h" #endif @@ -685,7 +687,8 @@ static bool trickle_charge(void) #ifdef HAVE_RTC static bool timedate_set(void) { - int timedate[7]; /* hour,minute,second,year,month,day,dayofweek */ + struct tm tm; + int timedate[8]; bool result; timedate[0] = rtc_read(0x03); /* hour */ @@ -695,67 +698,27 @@ static bool timedate_set(void) timedate[4] = rtc_read(0x06); /* month */ timedate[5] = rtc_read(0x05); /* day */ - /* day of week not read, calculated in set_time() */ - /* hour */ - timedate[0] = ((timedate[0] & 0x30) >> 4) * 10 + (timedate[0] & 0x0f); - /* minute */ - timedate[1] = ((timedate[1] & 0x70) >> 4) * 10 + (timedate[1] & 0x0f); - /* second */ - timedate[2] = ((timedate[2] & 0x70) >> 4) * 10 + (timedate[2] & 0x0f); - /* year */ - timedate[3] = ((timedate[3] & 0xf0) >> 4) * 10 + (timedate[3] & 0x0f); - /* month */ - timedate[4] = ((timedate[4] & 0x10) >> 4) * 10 + (timedate[4] & 0x0f); - /* day */ - timedate[5] = ((timedate[5] & 0x30) >> 4) * 10 + (timedate[5] & 0x0f); + /* Make a local copy of the time struct */ + memcpy(&tm, get_time(), sizeof(struct tm)); /* do some range checks */ /* This prevents problems with time/date setting after a power loss */ - if (timedate[0] < 0 || timedate[0] > 23 || - timedate[1] < 0 || timedate[1] > 59 || - timedate[2] < 0 || timedate[2] > 59 || - timedate[3] < 0 || timedate[3] > 99 || - timedate[4] < 1 || timedate[4] > 12 || - timedate[5] < 1 || timedate[5] > 31) + if (!valid_time(&tm)) { /* hour */ - timedate[0] = 0; - /* minute */ - timedate[1] = 0; - /* second */ - timedate[2] = 0; - /* year */ - timedate[3] = 3; - /* month */ - timedate[4] = 1; - /* day */ - timedate[5] = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_mday = 1; + tm.tm_mon = 0; + tm.tm_wday = 1; + tm.tm_year = 100; } - result = set_time(str(LANG_TIME),timedate); + result = set_time_screen(str(LANG_TIME), &tm); - if(timedate[0] != -1) { - /* hour */ - timedate[0] = ((timedate[0]/10) << 4 | timedate[0]%10) & 0x3f; - /* minute */ - timedate[1] = ((timedate[1]/10) << 4 | timedate[1]%10) & 0x7f; - /* second */ - timedate[2] = ((timedate[2]/10) << 4 | timedate[2]%10) & 0x7f; - /* year */ - timedate[3] = ((timedate[3]/10) << 4 | timedate[3]%10) & 0xff; - /* month */ - timedate[4] = ((timedate[4]/10) << 4 | timedate[4]%10) & 0x1f; - /* day */ - timedate[5] = ((timedate[5]/10) << 4 | timedate[5]%10) & 0x3f; - - rtc_write(0x03, timedate[0] | (rtc_read(0x03) & 0xc0)); /* hour */ - rtc_write(0x02, timedate[1] | (rtc_read(0x02) & 0x80)); /* minute */ - rtc_write(0x01, timedate[2] | (rtc_read(0x01) & 0x80)); /* second */ - rtc_write(0x07, timedate[3]); /* year */ - rtc_write(0x06, timedate[4] | (rtc_read(0x06) & 0xe0)); /* month */ - rtc_write(0x05, timedate[5] | (rtc_read(0x05) & 0xc0)); /* day */ - rtc_write(0x04, timedate[6] | (rtc_read(0x04) & 0xf8)); /* dayofweek */ - rtc_write(0x00, 0x00); /* 0.1 + 0.01 seconds */ + if(tm.tm_year != -1) { + set_time(&tm); } return result; } diff --git a/firmware/common/timefuncs.c b/firmware/common/timefuncs.c index 23444e2e43..e682454ce2 100644 --- a/firmware/common/timefuncs.c +++ b/firmware/common/timefuncs.c @@ -23,10 +23,28 @@ #include "timefuncs.h" #include "debug.h" +#ifndef SIMULATOR static struct tm tm; +#endif + +bool valid_time(struct tm *tm) +{ + if (tm->tm_hour < 0 || tm->tm_hour > 23 || + tm->tm_sec < 0 || tm->tm_sec > 59 || + tm->tm_min < 0 || tm->tm_min > 59 || + tm->tm_year < 100 || tm->tm_year > 199 || + tm->tm_mon < 0 || tm->tm_mon > 11 || + tm->tm_wday < 1 || tm->tm_wday > 7 || + tm->tm_mday < 1 || tm->tm_mday > 31) + return false; + else + return true; +} + struct tm *get_time(void) { +#ifndef SIMULATOR #ifdef HAVE_RTC char rtcbuf[8]; @@ -41,6 +59,8 @@ struct tm *get_time(void) tm.tm_mon = ((rtcbuf[6] & 0x10) >> 4) * 10 + (rtcbuf[6] & 0x0f) - 1; tm.tm_year = ((rtcbuf[7] & 0xf0) >> 4) * 10 + (rtcbuf[7] & 0x0f) + 100; tm.tm_wday = rtcbuf[4] & 0x07; + if(tm.tm_wday == 7) + tm.tm_wday = 0; tm.tm_yday = 0; /* Not implemented for now */ tm.tm_isdst = -1; /* Not implemented for now */ #else @@ -55,4 +75,44 @@ struct tm *get_time(void) tm.tm_isdst = -1; /* Not implemented for now */ #endif return &tm; +#else + time_t now = time(NULL); + return localtime(&now); +#endif +} + +int set_time(struct tm *tm) +{ +#ifdef HAVE_RTC + int rc; + int tmp; + + if (valid_time(tm)) + { + rc = rtc_write(1, ((tm->tm_sec/10) << 4) | (tm->tm_sec%10)); + rc |= rtc_write(2, ((tm->tm_min/10) << 4) | (tm->tm_min%10)); + rc |= rtc_write(3, ((tm->tm_hour/10) << 4) | (tm->tm_hour%10)); + tmp = tm->tm_wday; + if(tmp == 0) + tmp = 7; + rc |= rtc_write(4, tmp); + rc |= rtc_write(5, ((tm->tm_mday/10) << 4) | (tm->tm_mday%10)); + rc |= rtc_write(6, (((tm->tm_mon+1)/10) << 4) | ((tm->tm_mon+1)%10)); + rc |= rtc_write(7, (((tm->tm_year-100)/10) << 4) | ((tm->tm_year-100)%10)); + + rc |= rtc_write(8, 0x80); /* Out=1, calibration = 0 */ + + if(rc) + return -1; + else + return 0; + } + else + { + return -2; + } +#else + (void)tm; + return 0; +#endif } diff --git a/firmware/include/timefuncs.h b/firmware/include/timefuncs.h index 3845b946c5..5c6719e709 100644 --- a/firmware/include/timefuncs.h +++ b/firmware/include/timefuncs.h @@ -21,24 +21,11 @@ #define _TIMEFUNCS_H_ #include "config.h" - -#ifndef SIMULATOR - -struct tm -{ - int tm_sec; /* seconds */ - int tm_min; /* minutes */ - int tm_hour; /* hours */ - int tm_mday; /* day of the month */ - int tm_mon; /* month */ - int tm_year; /* year since 1900 */ - int tm_wday; /* day of the week */ - int tm_yday; /* day in the year */ - int tm_isdst; /* daylight saving time */ -}; - -#endif +#include +#include "time.h" struct tm *get_time(void); +int set_time(struct tm *tm); +bool valid_time(struct tm *tm); #endif /* _TIMEFUNCS_H_ */ diff --git a/uisimulator/common/stubs.c b/uisimulator/common/stubs.c index 98c574ffaa..fab61b8ed3 100644 --- a/uisimulator/common/stubs.c +++ b/uisimulator/common/stubs.c @@ -124,13 +124,6 @@ void backlight_set_on_when_charging(bool beep) (void)beep; } -/* original is in firmware/common/timefuncs.c */ -struct tm *get_time(void) -{ - time_t now = time(NULL); - return localtime(&now); -} - int rtc_read(int address) { time_t now = time(NULL); @@ -161,7 +154,7 @@ int rtc_read(int address) int rtc_write(int address, int value) { - DEBUGF("write %x to address %x\n", value, address); + DEBUGF("write %02x to address %02x\n", value, address); return 0; } diff --git a/uisimulator/win32/Makefile b/uisimulator/win32/Makefile index fe7086391b..05acb9c41c 100644 --- a/uisimulator/win32/Makefile +++ b/uisimulator/win32/Makefile @@ -97,7 +97,8 @@ else LCDSRSC = lcd-playersim.c lcd-player.c lcd-player-charset.c font-player.c endif FIRMSRCS = $(LCDSRSC) id3.c mp3data.c usb.c mpeg.c mp3_playback.c \ - powermgmt.c power.c sprintf.c buffer.c lcd-common.c strtok.c random.c + powermgmt.c power.c sprintf.c buffer.c lcd-common.c strtok.c random.c \ + timefuncs.c APPS = main.c tree.c menu.c credits.c main_menu.c icons.c language.c \ playlist.c wps.c wps-display.c settings.c status.c \ @@ -284,6 +285,9 @@ $(OBJDIR)/sprintf.o: $(COMMON)/sprintf.c $(OBJDIR)/strtok.o: $(COMMON)/strtok.c $(CC) $(CFLAGS) -c $< -o $@ +$(OBJDIR)/timefuncs.o: $(COMMON)/timefuncs.c + $(CC) $(CFLAGS) -c $< -o $@ + $(OBJDIR)/stubs.o: $(SIMCOMMON)/stubs.c $(CC) $(CFLAGS) -c $< -o $@ diff --git a/uisimulator/win32/timefuncs.h b/uisimulator/win32/timefuncs.h index c1b6ef8196..59e8b249eb 100644 --- a/uisimulator/win32/timefuncs.h +++ b/uisimulator/win32/timefuncs.h @@ -1,4 +1,7 @@ #include +#include /* struct tm defined */ struct tm *get_time(void); +int set_time(struct tm *tm); +bool valid_time(struct tm *tm); diff --git a/uisimulator/x11/Makefile b/uisimulator/x11/Makefile index fb609ea2c3..6fbc413a3c 100644 --- a/uisimulator/x11/Makefile +++ b/uisimulator/x11/Makefile @@ -97,7 +97,7 @@ else LCDSRSC = lcd-playersim.c lcd-player.c font-player.c lcd-player-charset.c endif FIRMSRCS = $(LCDSRSC) id3.c debug.c usb.c mpeg.c mp3_playback.c power.c\ - powermgmt.c panic.c mp3data.c sprintf.c buffer.c + powermgmt.c panic.c mp3data.c sprintf.c buffer.c timefuncs.c APPS = main.c tree.c menu.c credits.c main_menu.c language.c\ playlist.c wps.c wps-display.c settings.c status.c icons.c\ @@ -264,6 +264,9 @@ $(OBJDIR)/buffer.o: $(FIRMWAREDIR)/buffer.c $(OBJDIR)/ctype.o: $(COMMON)/ctype.c $(CC) $(CFLAGS) $(APPINCLUDES) -c $< -o $@ +$(OBJDIR)/timefuncs.o: $(COMMON)/timefuncs.c + $(CC) $(CFLAGS) $(APPINCLUDES) -c $< -o $@ + $(OBJDIR)/stubs.o: $(SIMCOMMON)/stubs.c $(CC) $(APPCFLAGS) -c $< -o $@ diff --git a/uisimulator/x11/timefuncs.h b/uisimulator/x11/timefuncs.h index c1b6ef8196..59e8b249eb 100644 --- a/uisimulator/x11/timefuncs.h +++ b/uisimulator/x11/timefuncs.h @@ -1,4 +1,7 @@ #include +#include /* struct tm defined */ struct tm *get_time(void); +int set_time(struct tm *tm); +bool valid_time(struct tm *tm); -- cgit v1.2.3