TM_RTC_Result_t TM_RTC_GetDateTimeFromUnix(TM_RTC_t* data, uint32_t unix) {
	uint16_t year;
	
	/* Store unix time to unix in struct */
	data->Unix = unix;
	/* Get seconds from unix */
	data->Seconds = unix % 60;
	/* Go to minutes */
	unix /= 60;
	/* Get minutes */
	data->Minutes = unix % 60;
	/* Go to hours */
	unix /= 60;
	/* Get hours */
	data->Hours = unix % 24;
	/* Go to days */
	unix /= 24;
	
	/* Get week day */
	/* Monday is day one */
	data->WeekDay = (unix + 3) % 7 + 1;

	/* Get year */
	year = 1970;
	while (1) {
		if (RTC_LEAP_YEAR(year)) {
			if (unix >= 366) {
				unix -= 366;
			} else {
				break;
			}
		} else if (unix >= 365) {
			unix -= 365;
		} else {
			break;
		}
		year++;
	}
	/* Get year in xx format */
	data->Year = (uint8_t) (year - 2000);
	/* Get month */
	for (data->Month = 0; data->Month < 12; data->Month++) {
		if (RTC_LEAP_YEAR(year) && unix >= (uint32_t)RTC_Months[1][data->Month]) {
			unix -= RTC_Months[1][data->Month];
		} else if (unix >= (uint32_t)RTC_Months[0][data->Month]) {
			unix -= RTC_Months[0][data->Month];
		} else {
			break;
		}
	}
	/* Get month */
	/* Month starts with 1 */
	data->Month++;
	/* Get date */
	/* Date starts with 1 */
	data->Day = unix + 1;

	/* Return OK */
	return TM_RTC_Result_Ok;
}
uint32_t TM_RTC_GetUnixTimeStamp(TM_RTC_t* data) {
	uint32_t days = 0, seconds = 0;
	uint16_t i;
	uint16_t year = (uint16_t) (data->Year + 2000);
	/* Year is below offset year */
	if (year < RTC_OFFSET_YEAR) {
		return 0;
	}
	/* Days in back years */
	for (i = RTC_OFFSET_YEAR; i < year; i++) {
		days += RTC_DAYS_IN_YEAR(i);
	}
	/* Days in current year */
	for (i = 1; i < data->Month; i++) {
		days += RTC_Months[RTC_LEAP_YEAR(year)][i - 1];
	}
	/* Day starts with 1 */
	days += data->Day - 1;
	seconds = days * RTC_SECONDS_PER_DAY;
	seconds += data->Hours * RTC_SECONDS_PER_HOUR;
	seconds += data->Minutes * RTC_SECONDS_PER_MINUTE;
	seconds += data->Seconds;
	
	/* seconds = days * 86400; */
	return seconds;
}
uint8_t TM_RTC_GetDaysInMonth(uint8_t month, uint8_t year) {
	/* Check input data */
	if (
		month == 0 ||
		month > 12
	) {
		/* Error */
		return 0;
	}
	
	/* Return days in month */
	return RTC_Months[RTC_LEAP_YEAR(2000 + year) ? 1 : 0][month - 1];
}
TM_RTC_Result_t TM_RTC_SetDateTime(TM_RTC_t* data, TM_RTC_Format_t format) {
	TM_RTC_t tmp;
	
	/* Check date and time validation */
	if (format == TM_RTC_Format_BCD) {
		tmp.Day = RTC_BCD2BIN(data->Day);
		tmp.Month = RTC_BCD2BIN(data->Month);
		tmp.Year = RTC_BCD2BIN(data->Year);
		tmp.Hours = RTC_BCD2BIN(data->Hours);
		tmp.Minutes = RTC_BCD2BIN(data->Minutes);
		tmp.Seconds = RTC_BCD2BIN(data->Seconds);
		tmp.WeekDay = RTC_BCD2BIN(data->WeekDay);
	} else {
		tmp.Day = data->Day;
		tmp.Month = data->Month;
		tmp.Year = data->Year;
		tmp.Hours = data->Hours;
		tmp.Minutes = data->Minutes;
		tmp.Seconds = data->Seconds;
		tmp.WeekDay = data->WeekDay;
	}
	
	/* Check year and month */
	if (
		tmp.Year > 99 || 
		tmp.Month == 0 || 
		tmp.Month > 12 ||
		tmp.Day == 0 ||
		tmp.Day > RTC_Months[RTC_LEAP_YEAR(2000 + tmp.Year) ? 1 : 0][tmp.Month - 1] ||
		tmp.Hours > 23 ||
		tmp.Minutes > 59 ||
		tmp.Seconds > 59 ||
		tmp.WeekDay == 0 ||
		tmp.WeekDay > 7
	) {
		/* Invalid date */
		return TM_RTC_Result_Error; 
	}
	
	/* Fill time */
	RTC_TimeStruct.Hours = data->Hours;
	RTC_TimeStruct.Minutes = data->Minutes;
	RTC_TimeStruct.Seconds = data->Seconds;
	
	/* Fill date */
	RTC_DateStruct.Date = data->Day;
	RTC_DateStruct.Month = data->Month;
	RTC_DateStruct.Year = data->Year;
	RTC_DateStruct.WeekDay = data->WeekDay;

	/* Set time */
	if (format == TM_RTC_Format_BCD) {
		HAL_RTC_SetTime(&hRTC, &RTC_TimeStruct, RTC_FORMAT_BCD);
	} else {
		HAL_RTC_SetTime(&hRTC, &RTC_TimeStruct, RTC_FORMAT_BIN);
	}
	
	/* Set date */
	if (format == TM_RTC_Format_BCD) {
		HAL_RTC_SetDate(&hRTC, &RTC_DateStruct, RTC_FORMAT_BCD);
	} else {
		HAL_RTC_SetDate(&hRTC, &RTC_DateStruct, RTC_FORMAT_BIN);
	}	
		
	/* Init RTC */
	HAL_RTC_Init(&hRTC);
	
	/* Return OK */
	return TM_RTC_Result_Ok;
}
示例#5
0
TM_RTC_Result_t TM_RTC_SetDateTime(TM_RTC_t* data, TM_RTC_Format_t format) {
	TM_RTC_t tmp;
	
	/* Check date and time validation */
	if (format == TM_RTC_Format_BCD) {
		tmp.date = RTC_BCD2BIN(data->date);
		tmp.month = RTC_BCD2BIN(data->month);
		tmp.year = RTC_BCD2BIN(data->year);
		tmp.hours = RTC_BCD2BIN(data->hours);
		tmp.minutes = RTC_BCD2BIN(data->minutes);
		tmp.seconds = RTC_BCD2BIN(data->seconds);
		tmp.day = RTC_BCD2BIN(data->day);
	} else {
		tmp.date = data->date;
		tmp.month = data->month;
		tmp.year = data->year;
		tmp.hours = data->hours;
		tmp.minutes = data->minutes;
		tmp.seconds = data->seconds;
		tmp.day = data->day;
	}
	
	/* Check year and month */
	if (
		tmp.year > 99 || 
		tmp.month == 0 || 
		tmp.month > 12 ||
		tmp.date == 0 ||
		tmp.date > TM_RTC_Months[RTC_LEAP_YEAR(2000 + tmp.year) ? 1 : 0][tmp.month - 1] ||
		tmp.hours > 23 ||
		tmp.minutes > 59 ||
		tmp.seconds > 59 ||
		tmp.day == 0 ||
		tmp.day > 7
	) {
		/* Invalid date */
		return TM_RTC_Result_Error; 
	}
	
	/* Fill time */
	RTC_TimeStruct.RTC_Hours = data->hours;
	RTC_TimeStruct.RTC_Minutes = data->minutes;
	RTC_TimeStruct.RTC_Seconds = data->seconds;
	/* Fill date */
	RTC_DateStruct.RTC_Date = data->date;
	RTC_DateStruct.RTC_Month = data->month;
	RTC_DateStruct.RTC_Year = data->year;
	RTC_DateStruct.RTC_WeekDay = data->day;
	
	/* Set the RTC time base to 1s and hours format to 24h */
	RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24;
	RTC_InitStruct.RTC_AsynchPrediv = RTC_ASYNC_PREDIV;
	RTC_InitStruct.RTC_SynchPrediv = RTC_SYNC_PREDIV;
	RTC_Init(&RTC_InitStruct);

	/* Set time */
	if (format == TM_RTC_Format_BCD) {
		RTC_SetTime(RTC_Format_BCD, &RTC_TimeStruct);
	} else {
		RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
	}
	
	/* Set date */
	if (format == TM_RTC_Format_BCD) {
		RTC_SetDate(RTC_Format_BCD, &RTC_DateStruct);
	} else {
		RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct);
	}	
	
	if (TM_RTC_Status != RTC_STATUS_ZERO) {
		/* Write backup registers */
		RTC_WriteBackupRegister(RTC_STATUS_REG, RTC_STATUS_TIME_OK);
	}
	
	/* Return OK */
	return TM_RTC_Result_Ok;
}