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; }
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; }