Ejemplo n.º 1
0
/**
 * add one to the seconds
 */
void inline add_second(s_time *time, uint8_t overflow) {
	time->second++;
	if (time->second >= 60) {
		time->second = 0;
		if (overflow) {
			add_minute(time, 1);
		}
	}
}
Ejemplo n.º 2
0
/**
 * State machine for menu and display
 */
void run_states(uint8_t state, s_time* time) {
	// State machine zum Ändern der Uhrzeit
	switch (0xf0 & state) {
	case STATE_MENU_SECOND:
		set_all_leds(1);
		if (b_pressed()) {
			add_second(time, 0);
		}
		display_seconds(*time);
		break;
	case STATE_MENU_MINUTE:
		set_all_leds(1);
		if (b_pressed()) {
			add_minute(time, 0);
		}
		display_minutes(*time);
		break;
	case STATE_MENU_HOUR:
		set_all_leds(1);
		if (b_pressed()) {
			add_hour(time);
		}
		display_hours(*time);
		break;
	case STATE_NONE:

		set_all_leds(0);

#ifdef WITH_ENLIGHT
		if (enlight > 0) {
#endif
			display_seconds(*time);
			display_minutes(*time);
			display_hours(*time);
#ifdef WITH_ENLIGHT
			enlight--;
		}
#endif

		add_second(time, 1);
		break;
	}
}
Ejemplo n.º 3
0
int 
main(void)
{
	the_time first_time,second_time;
	
	int a,b;
	a=12;
	b=36;

	set(&first_time,a,a);
	print_time(first_time);
	
	set(&second_time,a,b);
	print_time(second_time);

	add_minute(&second_time,183);
	print_time(second_time);

	printf("absoluate different of the times is : %d mins \n",abs_dif_time(&first_time,&second_time));

	return 0;
}
Ejemplo n.º 4
0
uint32_t
decode_time(uint8_t init_min, uint8_t minlen, uint32_t acc_minlen,
    const uint8_t * const buffer, struct tm * const time)
{
	struct tm newtime;
	uint32_t rval = 0;
	int16_t increase, i;
	uint8_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, utchour;
	int8_t centofs;
	bool generr, p1, p2, p3, ok;
	static uint32_t acc_minlen_partial, old_acc_minlen;
	static bool olderr, prev_toolong;

	memset(&newtime, 0, sizeof(newtime));
	/* Initially, set time offset to unknown */
	if (init_min == 2)
		time->tm_isdst = -1;
	newtime.tm_isdst = time->tm_isdst; /* save DST value */

	if (minlen < 59)
		rval |= DT_SHORT;
	if (minlen > 60)
		rval |= DT_LONG;

	if (buffer[0] == 1)
		rval |= DT_B0;
	if (buffer[20] == 0)
		rval |= DT_B20;

	if (buffer[17] == buffer[18])
		rval |= DT_DSTERR;

	generr = (rval != 0); /* do not decode if set */

	if (buffer[15] == 1)
		rval |= DT_XMIT;

	/* See if there are any partial / split minutes to be combined: */
	if (acc_minlen <= 59000) {
		acc_minlen_partial += acc_minlen;
		if (acc_minlen_partial >= 60000) {
			acc_minlen = acc_minlen_partial;
			acc_minlen_partial %= 60000;
		}
	}
	/* Calculate number of minutes to increase time with: */
	if (prev_toolong)
		increase = (int16_t)((acc_minlen - old_acc_minlen) / 60000);
	else
		increase = (int16_t)(acc_minlen / 60000);
	if (acc_minlen >= 60000)
		acc_minlen_partial %= 60000;
	/* Account for complete minutes with a short acc_minlen: */
	if (acc_minlen % 60000 > 59000) {
		increase++;
		acc_minlen_partial %= 60000;
	}

	prev_toolong = (minlen == 0xff);
	old_acc_minlen = acc_minlen - (acc_minlen % 60000);

	/* There is no previous time on the very first (partial) minute: */
	if (init_min < 2) {
		for (i = increase; increase > 0 && i > 0; i--)
			add_minute(time, true);
		for (i = increase; increase < 0 && i < 0; i++)
			substract_minute(time, false);
	}

	p1 = getpar(buffer, 21, 28);
	tmp0 = getbcd(buffer, 21, 24);
	tmp1 = getbcd(buffer, 25, 27);
	if (!p1 || tmp0 > 9 || tmp1 > 5) {
		rval |= DT_MIN;
		p1 = false;
	}
	if ((init_min == 2 || increase != 0) && p1 && !generr) {
		newtime.tm_min = (int)(tmp0 + 10 * tmp1);
		if (init_min == 0 && time->tm_min != newtime.tm_min)
			rval |= DT_MINJUMP;
	}

	p2 = getpar(buffer, 29, 35);
	tmp0 = getbcd(buffer, 29, 32);
	tmp1 = getbcd(buffer, 33, 34);
	if (!p2 || tmp0 > 9 || tmp1 > 2 || tmp0 + 10 * tmp1 > 23) {
		rval |= DT_HOUR;
		p2 = false;
	}
	if ((init_min == 2 || increase != 0) && p2 && !generr) {
		newtime.tm_hour = (int)(tmp0 + 10 * tmp1);
		if (init_min == 0 && time->tm_hour != newtime.tm_hour)
			rval |= DT_HOURJUMP;
	}

	p3 = getpar(buffer, 36, 58);
	tmp0 = getbcd(buffer, 36, 39);
	tmp1 = getbcd(buffer, 40, 41);
	tmp2 = getbcd(buffer, 42, 44);
	tmp3 = getbcd(buffer, 45, 48);
	tmp4 = getbcd(buffer, 50, 53);
	tmp5 = getbcd(buffer, 54, 57);
	if (!p3 || tmp0 > 9 || tmp0 + 10 * tmp1 == 0 ||
	    tmp0 + 10 * tmp1 > 31 || tmp2 == 0 || tmp3 > 9 ||
	    tmp3 + 10 * buffer[49] == 0 || tmp3 + 10 * buffer[49] > 12 ||
	    tmp4 > 9 || tmp5 > 9) {
		rval |= DT_DATE;
		p3 = false;
	}
	if ((init_min == 2 || increase != 0) && p3 && !generr) {
		newtime.tm_mday = (int)(tmp0 + 10 * tmp1);
		newtime.tm_mon = (int)(tmp3 + 10 * buffer[49]);
		newtime.tm_year = (int)(tmp4 + 10 * tmp5);
		newtime.tm_wday = (int)tmp2;
		if (init_min == 0 && time->tm_mday != newtime.tm_mday)
			rval |= DT_MDAYJUMP;
		if (init_min == 0 && time->tm_wday != newtime.tm_wday)
			rval |= DT_WDAYJUMP;
		if (init_min == 0 && time->tm_mon != newtime.tm_mon)
			rval |= DT_MONTHJUMP;
		centofs = century_offset(newtime);
		if (centofs == -1) {
			rval |= DT_DATE;
			p3 = false;
		} else {
			if (init_min == 0 && time->tm_year !=
			    (int)(BASEYEAR + 100 * centofs + newtime.tm_year))
				rval |= DT_YEARJUMP;
			newtime.tm_year += BASEYEAR + 100 * centofs;
			if (newtime.tm_mday > (int)lastday(newtime)) {
				rval |= DT_DATE;
				p3 = false;
			}
		}
	}

	ok = !generr && p1 && p2 && p3; /* shorthand */

	utchour = get_utchour(*time);

	/*
	 * h==23, last day of month (UTC) or h==0, first day of next month (UTC)
	 * according to IERS Bulletin C
	 * flag still set at 00:00 UTC, prevent DT_LEAPERR
	 */
	if (buffer[19] == 1 && ok) {
		if (time->tm_mday == 1 && is_leapsecmonth(*time) &&
		    ((time->tm_min > 0 && utchour == 23) ||
		    (time->tm_min == 0 && utchour == 0)))
			announce |= ANN_LEAP;
		else {
			announce &= ~ANN_LEAP;
			rval |= DT_LEAPERR;
		}
	}

	/* process possible leap second, always reset announcement at hh:00 */
	if (((announce & ANN_LEAP) == ANN_LEAP) && time->tm_min == 0) {
		announce &= ~ANN_LEAP;
		rval |= DT_LEAP;
		if (minlen == 59) {
			/* leap second processed, but missing */
			rval |= DT_SHORT;
			ok = false;
			generr = true;
		} else if (minlen == 60 && buffer[59] == 1)
			rval |= DT_LEAPONE;
	}
	if ((minlen == 60) && ((rval & DT_LEAP) == 0)) {
		/* leap second not processed, so bad minute */
		rval |= DT_LONG;
		ok = false;
		generr = true;
	}

	/* h==0 (UTC) because sz->wz -> h==2 and wz->sz -> h==1,
	 * last Sunday of month (reference?) */
	if (buffer[16] == 1 && ok) {
		if ((time->tm_wday == 7 && time->tm_mday > (int)(lastday(*time) - 7) &&
		    (time->tm_mon == (int)summermonth ||
		    time->tm_mon == (int)wintermonth)) && ((time->tm_min > 0 &&
		    utchour == 0) || (time->tm_min == 0 &&
		    utchour == 1 + buffer[17] - buffer[18])))
			announce |= ANN_CHDST; /* time zone just changed */
		else {
			announce &= ~ANN_CHDST;
			rval |= DT_CHDSTERR;
		}
	}

	if ((int)buffer[17] != time->tm_isdst || (int)buffer[18] == time->tm_isdst) {
		/* Time offset change is OK if:
		 * announced and time is Sunday, lastday, 01:00 UTC
		 * there was an error but not any more (needed if decoding at
		 *   startup is problematic)
		 * initial state (otherwise DST would never be valid)
		 */
		if ((((announce & ANN_CHDST) == ANN_CHDST) && time->tm_min == 0) ||
		    (olderr && ok) ||
		    ((rval & DT_DSTERR) == 0 && time->tm_isdst == -1))
			newtime.tm_isdst = (int)buffer[17]; /* expected change */
		else {
			if ((rval & DT_DSTERR) == 0)
				rval |= DT_DSTJUMP; /* sudden change, ignore */
			ok = false;
		}
	}
	/* check if DST is within expected date range */
	if ((time->tm_mon > (int)summermonth && time->tm_mon < (int)wintermonth) ||
	    (time->tm_mon == (int)summermonth && time->tm_wday < 7 &&
	      (int)(lastday(*time)) - time->tm_mday < 7) ||
	    (time->tm_mon == (int)summermonth && time->tm_wday == 7 &&
	      (int)(lastday(*time)) - time->tm_mday < 7 && utchour > 0) ||
	    (time->tm_mon == (int)wintermonth && time->tm_wday < 7 &&
	      (int)(lastday(*time)) - time->tm_mday >= 7) ||
	    (time->tm_mon == (int)wintermonth && time->tm_wday == 7 &&
	      (int)(lastday(*time)) - time->tm_mday < 7 &&
		(utchour >= 22 /* previous day */ || utchour == 0))) {
		/* expect DST */
		if (newtime.tm_isdst == 0 && (announce & ANN_CHDST) == 0 &&
		    utchour < 24) {
			rval |= DT_DSTJUMP; /* sudden change */
			ok = false;
		}
	} else {
		/* expect non-DST */
		if (newtime.tm_isdst == 1 && (announce & ANN_CHDST) == 0 &&
		    utchour < 24) {
			rval |= DT_DSTJUMP; /* sudden change */
			ok = false;
		}
	}
	/* done with DST */
	if (((announce & ANN_CHDST) == ANN_CHDST) && time->tm_min == 0) {
		announce &= ~ANN_CHDST;
		rval |= DT_CHDST;
	}
	newtime.tm_gmtoff = 3600 * (newtime.tm_isdst + 1);

	if (olderr && ok)
		olderr = false;
	if (!generr) {
		if (p1)
			time->tm_min = newtime.tm_min;
		if (p2)
			time->tm_hour = newtime.tm_hour;
		if (p3) {
			time->tm_mday = newtime.tm_mday;
			time->tm_mon = newtime.tm_mon;
			time->tm_year = newtime.tm_year;
			time->tm_wday = newtime.tm_wday;
		}
		if ((rval & DT_DSTJUMP) == 0) {
			time->tm_isdst = newtime.tm_isdst;
			time->tm_gmtoff = newtime.tm_gmtoff;
		}
	}
	if (!ok)
		olderr = true;

	return rval | announce;
}