2015-07-10 06:01:56 -07:00
/**
* @ file rtc_helper . cpp
* @ brief Real Time Clock helper
*
* @ date Feb 5 , 2014
2020-01-13 18:57:43 -08:00
* @ author Andrey Belomutskiy , ( c ) 2012 - 2020
2015-07-10 06:01:56 -07:00
*/
# include <string.h>
# include <time.h>
2018-09-16 19:26:57 -07:00
# include "global.h"
2019-07-03 18:48:04 -07:00
# include "os_access.h"
2019-07-06 17:15:49 -07:00
# include "os_util.h"
2015-07-10 06:01:56 -07:00
# include "rtc_helper.h"
2021-04-28 19:41:25 -07:00
# include <sys/time.h>
2015-07-10 06:01:56 -07:00
2019-04-12 17:52:51 -07:00
# if EFI_RTC
2017-03-21 11:58:14 -07:00
static RTCDateTime timespec ;
2015-07-10 06:01:56 -07:00
2017-08-25 15:37:59 -07:00
extern bool rtcWorks ;
2015-07-10 06:01:56 -07:00
# endif /* EFI_RTC */
void date_set_tm ( struct tm * timp ) {
( void ) timp ;
2019-04-12 17:52:51 -07:00
# if EFI_RTC
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 ) {
2019-04-12 17:52:51 -07:00
# if EFI_RTC
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 */
}
2021-04-28 19:41:25 -07:00
# if EFI_PROD_CODE
// Lua needs this function, but we don't necessarily have to implement it
extern " C " int _gettimeofday ( timeval * tv , void * tzvp ) {
return 0 ;
}
# endif
2017-03-21 11:58:14 -07:00
static time_t GetTimeUnixSec ( void ) {
2019-04-12 17:52:51 -07:00
# if EFI_RTC
2017-03-21 11:58:14 -07:00
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 ) {
2019-04-12 17:52:51 -07:00
# if EFI_RTC
2017-03-21 11:58:14 -07:00
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 ] ;
2018-07-25 20:03:04 -07:00
efiAssertVoid ( CUSTOM_ERR_6666 , 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 ) {
2019-04-12 17:52:51 -07:00
# if EFI_RTC
2020-05-17 14:02:22 -07:00
strcpy ( lcd_str , " 000000_000000 \0 " ) ;
2016-08-08 21:03:08 -07:00
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 ;
}
2020-05-17 14:02:22 -07:00
put2 ( 0 , lcd_str , timp . tm_year % 100 ) ; // Years since 1900 - format as just the last two digits
put2 ( 2 , lcd_str , timp . tm_mon + 1 ) ; // months since January 0-11
put2 ( 4 , lcd_str , timp . tm_mday ) ; // day of the month 1-31
put2 ( 7 , lcd_str , timp . tm_hour ) ; // hours since midnight 0-23
put2 ( 9 , lcd_str , timp . tm_min ) ; // Minutes
put2 ( 11 , lcd_str , timp . tm_sec ) ; // seconds
2016-08-08 21:03:08 -07:00
return true ;
# else
lcd_str [ 0 ] = 0 ;
return false ;
# endif
}
2015-07-10 06:01:56 -07:00
void dateToString ( char * lcd_str ) {
2019-04-12 17:52:51 -07:00
# if EFI_RTC
2015-07-10 06:01:56 -07:00
// 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 */
}
2019-04-12 17:52:51 -07:00
# if EFI_RTC
2015-07-10 06:01:56 -07:00
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 ) {
2021-04-19 05:11:59 -07:00
efiPrintf ( " incorrect time in RTC cell " ) ;
2015-07-10 06:01:56 -07:00
} else {
2021-04-19 05:11:59 -07:00
efiPrintf ( " %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
2021-04-21 12:33:40 -07:00
efiPrintf ( " Current RTC localtime is: %04u-%02u-%02u %02u:%02u:%02u w=%d " , timp . tm_year + 1900 , timp . tm_mon + 1 , timp . tm_mday , timp . tm_hour ,
2017-08-25 15:37:59 -07:00
timp . tm_min , timp . tm_sec , rtcWorks ) ;
2015-07-10 06:01:56 -07:00
}
}
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 ;
}
}
2021-04-19 05:11:59 -07:00
efiPrintf ( " date_set Date parameter %s is wrong " , strDate ) ;
2015-07-10 06:01:56 -07:00
}
# endif /* EFI_RTC */
void initRtc ( void ) {
2019-04-12 17:52:51 -07:00
# if EFI_RTC
2017-03-21 11:58:14 -07:00
GetTimeUnixSec ( ) ; // this would test RTC, see 'rtcWorks' variable, see #311
2021-04-19 05:11:59 -07:00
efiPrintf ( " initRtc() " ) ;
2016-09-15 19:02:00 -07:00
# endif /* EFI_RTC */
2015-07-10 06:01:56 -07:00
}