2015-07-10 06:01:56 -07:00
/**
* @ file rtc_helper . cpp
* @ brief Real Time Clock helper
*
* @ date Feb 5 , 2014
2017-01-03 03:05:22 -08:00
* @ author Andrey Belomutskiy , ( c ) 2012 - 2017
2015-07-10 06:01:56 -07:00
*/
# include <string.h>
# include <time.h>
# include "main.h"
# include "rfiutil.h"
# include "rtc_helper.h"
# if EFI_RTC || defined(__DOXYGEN__)
static LoggingWithStorage logger ( " RTC " ) ;
2017-03-21 11:58:14 -07:00
static RTCDateTime timespec ;
2015-07-10 06:01:56 -07:00
# endif /* EFI_RTC */
void date_set_tm ( struct tm * timp ) {
( void ) timp ;
# if EFI_RTC || defined(__DOXYGEN__)
2017-03-21 11:58:14 -07:00
rtcConvertStructTmToDateTime ( timp , 0 , & timespec ) ;
rtcSetTime ( & RTCD1 , & timespec ) ;
2015-07-10 06:01:56 -07:00
# endif /* EFI_RTC */
}
void date_get_tm ( struct tm * timp ) {
# if EFI_RTC || defined(__DOXYGEN__)
2017-03-21 11:58:14 -07:00
rtcGetTime ( & RTCD1 , & timespec ) ;
rtcConvertDateTimeToStructTm ( & timespec , timp , NULL ) ;
2015-07-10 06:01:56 -07:00
# endif /* EFI_RTC */
}
2017-03-21 11:58:14 -07:00
static time_t GetTimeUnixSec ( void ) {
# if EFI_RTC || defined(__DOXYGEN__)
struct tm tim ;
rtcGetTime ( & RTCD1 , & timespec ) ;
rtcConvertDateTimeToStructTm ( & timespec , & tim , NULL ) ;
return mktime ( & tim ) ;
2017-05-02 10:34:01 -07:00
# else
return ( time_t ) 0 ;
2017-03-21 11:58:14 -07:00
# endif
}
static void SetTimeUnixSec ( time_t unix_time ) {
# if EFI_RTC || defined(__DOXYGEN__)
struct tm tim ;
2017-04-01 22:02:58 -07:00
# if defined __GNUC__
struct tm * canary ;
2017-03-21 11:58:14 -07:00
/* If the conversion is successful the function returns a pointer
to the object the result was written into . */
canary = localtime_r ( & unix_time , & tim ) ;
osalDbgCheck ( & tim = = canary ) ;
2017-04-01 22:02:58 -07:00
# else
2017-04-01 22:15:03 -07:00
struct tm * t = localtime ( & unix_time ) ;
memcpy ( & tim , t , sizeof ( struct tm ) ) ;
2017-04-01 22:02:58 -07:00
# endif
2017-03-21 11:58:14 -07:00
rtcConvertStructTmToDateTime ( & tim , 0 , & timespec ) ;
rtcSetTime ( & RTCD1 , & timespec ) ;
# endif
}
2016-08-08 21:03:08 -07:00
static void put2 ( int offset , char * lcd_str , int value ) {
2016-08-09 21:04:24 -07:00
static char buff [ _MAX_FILLER ] ;
efiAssertVoid ( value > = 0 & & value < 100 , " value " ) ;
2016-08-08 21:03:08 -07:00
itoa10 ( buff , value ) ;
if ( value < 10 ) {
lcd_str [ offset ] = ' 0 ' ;
lcd_str [ offset + 1 ] = buff [ 0 ] ;
} else {
lcd_str [ offset ] = buff [ 0 ] ;
lcd_str [ offset + 1 ] = buff [ 1 ] ;
}
}
2017-08-22 21:46:34 -07:00
/**
* @ return true if we seem to know current date , false if no valid RTC state
*/
2016-08-08 21:03:08 -07:00
bool dateToStringShort ( char * lcd_str ) {
# if EFI_RTC || defined(__DOXYGEN__)
strcpy ( lcd_str , " 0000_000000 \0 " ) ;
struct tm timp ;
2017-03-21 11:58:14 -07:00
date_get_tm ( & timp ) ;
2016-08-08 21:03:08 -07:00
if ( timp . tm_year < 116 | | timp . tm_year > 130 ) {
// 2016 to 2030 is the valid range
lcd_str [ 0 ] = 0 ;
return false ;
}
2017-08-22 21:46:34 -07:00
put2 ( 0 , lcd_str , timp . tm_mon + 1 ) ; // months since January 0-11
put2 ( 2 , lcd_str , timp . tm_mday ) ; // day of the month 1-31
put2 ( 5 , lcd_str , timp . tm_hour ) ; // hours since midnight 0-23
2016-08-08 21:03:08 -07:00
put2 ( 7 , lcd_str , timp . tm_min ) ;
put2 ( 9 , lcd_str , timp . tm_sec ) ;
return true ;
# else
lcd_str [ 0 ] = 0 ;
return false ;
# endif
}
2015-07-10 06:01:56 -07:00
void dateToString ( char * lcd_str ) {
# if EFI_RTC || defined(__DOXYGEN__)
// todo:
// re-implement this along the lines of chvprintf("%04u-%02u-%02u %02u:%02u:%02u\r\n", timp.tm_year + 1900, timp.tm_mon + 1, timp.tm_mday, timp.tm_hour,
// timp.tm_min, timp.tm_sec);
// this would require a temporary mem stream - see datalogging and other existing usages
strcpy ( lcd_str , " 00/00 00:00:00 \0 " ) ;
struct tm timp ;
2017-03-21 11:58:14 -07:00
date_get_tm ( & timp ) ; // get RTC date/time
2015-07-10 06:01:56 -07:00
2016-08-08 21:03:08 -07:00
put2 ( 0 , lcd_str , timp . tm_mon + 1 ) ;
put2 ( 3 , lcd_str , timp . tm_mday ) ;
put2 ( 6 , lcd_str , timp . tm_hour ) ;
put2 ( 9 , lcd_str , timp . tm_min ) ;
put2 ( 12 , lcd_str , timp . tm_sec ) ;
2015-07-10 06:01:56 -07:00
# else
lcd_str [ 0 ] = 0 ;
# endif /* EFI_RTC */
}
# if EFI_RTC || defined(__DOXYGEN__)
void printDateTime ( void ) {
static time_t unix_time ;
struct tm timp ;
2017-03-21 11:58:14 -07:00
unix_time = GetTimeUnixSec ( ) ;
2015-07-10 06:01:56 -07:00
if ( unix_time = = - 1 ) {
scheduleMsg ( & logger , " incorrect time in RTC cell " ) ;
} else {
scheduleMsg ( & logger , " %D - unix time " , unix_time ) ;
2017-03-21 11:58:14 -07:00
date_get_tm ( & timp ) ;
2015-07-10 06:01:56 -07:00
appendMsgPrefix ( & logger ) ;
2017-08-22 21:46:34 -07:00
appendPrintf ( & logger , " Current RTC localtime is: %04u-%02u-%02u %02u:%02u:%02u " , timp . tm_year + 1900 , timp . tm_mon + 1 , timp . tm_mday , timp . tm_hour ,
2015-07-10 06:01:56 -07:00
timp . tm_min , timp . tm_sec ) ;
appendMsgPostfix ( & logger ) ;
scheduleLogging ( & logger ) ;
}
}
void setDateTime ( const char * strDate ) {
if ( strlen ( strDate ) > 0 ) {
2016-08-09 18:03:16 -07:00
time_t unix_time = atoi ( strDate ) ;
2015-07-10 06:01:56 -07:00
if ( unix_time > 0 ) {
2017-03-21 11:58:14 -07:00
SetTimeUnixSec ( unix_time ) ;
2015-07-10 06:01:56 -07:00
printDateTime ( ) ;
return ;
}
}
scheduleMsg ( & logger , " date_set Date parameter %s is wrong \r \n " , strDate ) ;
}
# endif /* EFI_RTC */
void initRtc ( void ) {
# if EFI_RTC || defined(__DOXYGEN__)
2017-03-21 11:58:14 -07:00
GetTimeUnixSec ( ) ; // this would test RTC, see 'rtcWorks' variable, see #311
2015-07-10 06:01:56 -07:00
printMsg ( & logger , " initRtc() " ) ;
2016-09-15 19:02:00 -07:00
# endif /* EFI_RTC */
2015-07-10 06:01:56 -07:00
}