Browse Source

Merge pull request #27 from rdmiller3/DaylightSavingTime

Daylight saving time
master
Daniel Poelzleithner 11 years ago
parent
commit
ee5008d660
  1. 23
      driver/timer.c
  2. 11
      logic/date.c
  3. 173
      logic/dst.c
  4. 35
      logic/dst.h
  5. 9
      logic/rfsimpliciti.c
  6. 2
      makefile
  7. 9
      tools/config.py

23
driver/timer.c

@ -85,6 +85,11 @@
#include "sidereal.h"
#endif
#if (CONFIG_DST > 0)
#include "dst.h"
#include "date.h"
#endif
#ifdef CONFIG_STRENGTH
#include "strength.h"
#endif
@ -375,6 +380,24 @@ __interrupt void TIMER0_A0_ISR(void)
if (sAlarm.hourly == ALARM_ENABLED) {
request.flag.alarm_buzzer = 1;
}
#if (CONFIG_DST > 0)
if ((sTime.hour == 1) &&
(dst_state == 0) &&
dst_isDateInDST(sDate.month, sDate.day))
{
// spring forward
sTime.hour++;
dst_state = 1;
}
if ((sTime.hour == 2) &&
(dst_state != 0) &&
(!dst_isDateInDST(sDate.month, sDate.day)))
{
// fall back
sTime.hour--;
dst_state = 0;
}
#endif
}
// Check if alarm needs to be turned on
check_alarm();

11
logic/date.c

@ -93,6 +93,10 @@ void reset_date(void)
// Show default display
sDate.view = 0;
#if (CONFIG_DST > 0)
dst_calculate_dates();
#endif
}
@ -159,6 +163,10 @@ void add_day(void)
sDate.day = 1;
sDate.month = 1;
sDate.year++;
#if (CONFIG_DST > 0)
dst_calculate_dates();
#endif
}
}
// Indicate to display function that new value is available
@ -222,6 +230,9 @@ void mx_date(line_t line)
if(sSidereal_time.sync>0)
sync_sidereal();
#endif
#if (CONFIG_DST > 0)
dst_calculate_dates();
#endif
// Full display update is done when returning from function
break;

173
logic/dst.c

@ -0,0 +1,173 @@
/*
Daylight Saving Time for OpenChronos on the TI ez430 chronos watch.
Copyright 2011 Rick Miller <rdmiller3@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "project.h"
#if (CONFIG_DST > 0)
// driver
#include "altitude.h"
#include "display.h"
#include "vti_ps.h"
#include "ports.h"
#include "timer.h"
#include "stopwatch.h"
// logic
#include "user.h"
#include "clock.h"
#include "date.h"
#include "dst.h"
#include "menu.h"
struct dst_date_struct dst_dates[2];
u8 dst_state; // 0=ST, 1=DST
u8 dst_day_of_week(u16 year, u8 month, u8 day);
void dst_init(void)
{
dst_calculate_dates();
}
#define N_SUN_OF_MON(n,mon) (((n)*7)-dst_day_of_week(sDate.year,(mon),((n)*7)))
#define LAST_SUN_OF_MON(mon,days) ((days)-dst_day_of_week(sDate.year,(mon),(days)))
void dst_calculate_dates(void)
{
// This should be run whenever sDate.year gets changed.
#if (CONFIG_DST == 1)
// DST in US/Canada: 2nd Sun in Mar to 1st Sun in Nov.
dst_dates[0].month = 3;
dst_dates[0].day = N_SUN_OF_MON(2, 3);
dst_dates[1].month = 11;
dst_dates[1].day = N_SUN_OF_MON(1, 11);
#endif
#if (CONFIG_DST == 2)
// DST in Mexico: first Sun in Apr to last Sun in Oct.
dst_dates[0].month = 4;
dst_dates[0].day = N_SUN_OF_MON(1, 4);
dst_dates[1].month = 10;
dst_dates[1].day = LAST_SUN_OF_MON(10, 31);
#endif
#if (CONFIG_DST == 3)
// DST in Brazil: third Sun in Oct to third Sun in Feb.
dst_dates[0].month = 10;
dst_dates[0].day = N_SUN_OF_MON(3, 10);
dst_dates[1].month = 2;
dst_dates[1].day = N_SUN_OF_MON(3, 2);
#endif
#if (CONFIG_DST == 4)
// DST in EU/UK: last Sun in Mar to last Sun in Oct.
dst_dates[0].month = 3;
dst_dates[0].day = LAST_SUN_OF_MON(3, 31);
dst_dates[1].month = 10;
dst_dates[1].day = LAST_SUN_OF_MON(10, 31);
#endif
#if (CONFIG_DST == 5)
// DST in Australia: first Sun in Oct to first Sun in Apr.
dst_dates[0].month = 10;
dst_dates[0].day = N_SUN_OF_MON(1, 10);
dst_dates[1].month = 4;
dst_dates[1].day = N_SUN_OF_MON(1, 4);
#endif
#if (CONFIG_DST == 6)
// DST in New Zealand: last Sun in Sep to first Sun in Apr.
dst_dates[0].month = 9;
dst_dates[0].day = LAST_SUN_OF_MON(9, 30);
dst_dates[1].month = 4;
dst_dates[1].day = N_SUN_OF_MON(1, 4);
#endif
// This test may be wrong if you set your watch
// on the time-change day.
dst_state = (dst_isDateInDST(sDate.month, sDate.day)) ?
1 : 0;
}
#define DSTNUM(x,y) (((u16)(x)*100)+(u16)(y))
u8 dst_isDateInDST(u8 month, u8 day)
{
if (dst_dates[0].month < dst_dates[1].month)
{
// Northern hemisphere
return
((DSTNUM(month,day)>=DSTNUM(dst_dates[0].month,dst_dates[0].day)) &&
(DSTNUM(month,day)<DSTNUM(dst_dates[1].month,dst_dates[1].day)));
}
else
{
// Southern hemisphere
return (!(
((DSTNUM(month,day)>=DSTNUM(dst_dates[1].month,dst_dates[1].day)) &&
(DSTNUM(month,day)<DSTNUM(dst_dates[0].month,dst_dates[0].day)))));
}
}
u8 dst_day_of_week(u16 year, u8 month, u8 day)
{
// Calculate days since 2000-01-01
u32 tmp = ((u32)sDate.year % 200) * 365;
tmp += ((sDate.year % 200) / 4); // leap days
switch (sDate.month) // using lots of drop-through!
{
case 12:
tmp += 30; // for nov
case 11:
tmp += 31; // for oct
case 10:
tmp += 30; // for sep
case 9:
tmp += 31; // for aug
case 8:
tmp += 31; // for jul
case 7:
tmp += 30; // for jun
case 6:
tmp += 31; // for may
case 5:
tmp += 30; // for apr
case 4:
tmp += 31; // for mar
case 3:
tmp += 28; // for feb
if ((sDate.year % 4) == 0)
{
tmp++;
}
case 2:
tmp += 31; // for jan
case 1:
default:
// do nothing
break;
}
tmp += sDate.day;
tmp--; // because day-of-month is 1-based (2000-01-01 is the ZERO day).
// day zero (2000-01-01) was a Saturday.
return (u8)((tmp + 6) % 7);
}
#endif /* (CONFIG_DST > 0) */

35
logic/dst.h

@ -0,0 +1,35 @@
/*
Daylight Saving Time for OpenChronos on the TI ez430 chronos watch.
Copyright 2011 Rick Miller <rdmiller3@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DST_H_
#define DST_H_
struct dst_date_struct
{
u8 month;
u8 day;
};
extern struct dst_date_struct dst_dates[];
extern u8 dst_state; // 0=ST, 1=DST
void dst_init(void);
void dst_calculate_dates(void);
u8 dst_isDateInDST(u8 month, u8 day);
#endif

9
logic/rfsimpliciti.c

@ -76,6 +76,11 @@
#ifdef CONFIG_SIDEREAL
#include "sidereal.h"
#endif
#if (CONFIG_DST > 0)
#include "dst.h"
#endif
// *************************************************************************************************
// Defines section
@ -705,6 +710,10 @@ void simpliciti_sync_decode_ap_cmd_callback(void)
sAlarm.hour = simpliciti_data[8];
sAlarm.minute = simpliciti_data[9];
#endif
#if (CONFIG_DST > 0)
dst_calculate_dates();
#endif
// Set temperature and temperature offset
t1 = (s16)((simpliciti_data[10]<<8) + simpliciti_data[11]);
offset = t1 - (sTemp.degrees - sTemp.offset);

2
makefile

@ -21,7 +21,7 @@ CC_INCLUDE = -I$(PROJ_DIR)/ -I$(PROJ_DIR)/include/ -I$(PROJ_DIR)/gcc/ -I$(PROJ_D
CC_COPT = $(CC_CMACH) $(CC_DMACH) $(CC_DOPT) $(CC_INCLUDE)
LOGIC_SOURCE = logic/acceleration.c logic/alarm.c logic/altitude.c logic/battery.c logic/clock.c logic/date.c logic/menu.c logic/rfbsl.c logic/rfsimpliciti.c logic/stopwatch.c logic/temperature.c logic/test.c logic/user.c logic/phase_clock.c logic/eggtimer.c logic/prout.c logic/vario.c logic/sidereal.c logic/strength.c \
logic/sequence.c logic/gps.c
logic/sequence.c logic/gps.c logic/dst.c
LOGIC_O = $(addsuffix .o,$(basename $(LOGIC_SOURCE)))

9
tools/config.py

@ -161,6 +161,15 @@ DATA["CONFIG_SIDEREAL"] = {
"This does NOT replace the normal clock which is still available and working."
}
DATA["CONFIG_DST"] = {
"name": "Daylight Saving Time",
"depends": [],
"default": 0,
"type": "choices",
"values": [(0, "No DST"), (1, "US/Canada"), (2, "Mexico"), (3, "Brazil"), (4, "EU/UK/Eastern Europe"), (5, "Australia"), (6, "New Zealand")],
"help": "Automatically adjust Clock for Daylight Saving Time"
}
DATA["CONFIG_INFOMEM"] = {
"name": "Information Memory Driver (2934 bytes, requires sidereal clock)",

Loading…
Cancel
Save