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
*/
2021-08-03 19:05:01 -07:00
# include "pch.h"
2022-11-23 12:53:16 -08:00
# include <string.h>
2022-09-07 12:56:45 -07:00
2015-07-10 06:01:56 -07:00
# include "rtc_helper.h"
2022-11-09 03:56:42 -08:00
2022-11-23 12:53:16 -08:00
# if EFI_RTC
# include "rusefi_types.h"
# endif // EFI_RTC
2022-11-09 03:56:42 -08:00
# if EFI_PROD_CODE
2021-04-28 19:41:25 -07:00
# include <sys/time.h>
2015-07-10 06:01:56 -07:00
2022-11-09 03:56:42 -08:00
// Lua needs this function, but we don't necessarily have to implement it
extern " C " int _gettimeofday ( timeval * tv , void * tzvp ) {
( void ) tv ; ( void ) tzvp ;
return 0 ;
}
# endif // EFI_PROD_CODE
2019-04-12 17:52:51 -07:00
# if EFI_RTC
2022-11-23 12:53:16 -08:00
void initRtc ( ) {
efiPrintf ( " initRtc() " ) ;
2023-01-03 12:01:51 -08:00
printDateTime ( ) ; // this would test RTC, see #311
2015-07-10 06:01:56 -07:00
}
2022-11-23 12:53:16 -08:00
static const char * const monthAbbrs [ ] = {
" Jan " , " Feb " , " Mar " ,
" Apr " , " May " , " Jun " ,
" Jul " , " Aug " , " Sep " ,
" Oct " , " Nov " , " Dec "
} ;
void printRtcDateTime ( ) {
efidatetime_t dateTime = getRtcDateTime ( ) ;
// prints the date like: 19 sep 2022 21:19:55
2024-06-10 00:51:14 -07:00
efiPrintf ( " Current RTC time: %02u %s %04lu %02u:%02u:%02u " ,
2022-11-23 12:53:16 -08:00
dateTime . day , monthAbbrs [ dateTime . month - 1 ] , dateTime . year ,
dateTime . hour , dateTime . minute , dateTime . second ) ;
2021-04-28 19:41:25 -07:00
}
2022-11-23 12:53:16 -08:00
void setRtcDateTime ( efidatetime_t const * const dateTime ) {
RTCDateTime timespec = convertRtcDateTimeFromEfi ( dateTime ) ;
rtcSetTime ( & RTCD1 , & timespec ) ;
}
2022-09-20 02:28:42 -07:00
2024-08-28 18:05:47 -07:00
static time_t rtc_encode ( const RTCDateTime * timespec ) {
struct tm tim ;
2024-08-31 13:44:53 -07:00
// todo: looks like this pulls a lot of library code? 4K+?
// todo: reimplement lighter? https://github.com/rusefi/rusefi/issues/6876
2024-08-28 18:05:47 -07:00
rtcConvertDateTimeToStructTm ( timespec , & tim , NULL ) ;
return mktime ( & tim ) ;
}
uint32_t getEpochTime ( ) {
RTCDateTime timespec ;
rtcGetTime ( & RTCD1 , & timespec ) ;
return rtc_encode ( & timespec ) ;
}
2022-11-23 12:53:16 -08:00
efidatetime_t getRtcDateTime ( ) {
RTCDateTime timespec ;
2022-09-20 02:28:42 -07:00
rtcGetTime ( & RTCD1 , & timespec ) ;
2022-11-23 12:53:16 -08:00
return convertRtcDateTimeToEfi ( & timespec ) ;
2017-03-21 11:58:14 -07:00
}
2022-11-23 12:53:16 -08:00
efidatetime_t convertRtcDateTimeToEfi ( RTCDateTime const * const timespec ) {
uint32_t second = timespec - > millisecond / 1000 ;
uint16_t minute = second / 60 ;
second - = minute * 60 ;
uint8_t hour = minute / 60 ;
minute - = hour * 60 ;
efidatetime_t const dateTime = {
. year = timespec - > year + RTC_BASE_YEAR ,
. month = ( uint8_t ) timespec - > month ,
. day = ( uint8_t ) timespec - > day ,
. hour = hour ,
. minute = ( uint8_t ) minute ,
. second = ( uint8_t ) second ,
} ;
return dateTime ;
}
2017-03-21 11:58:14 -07:00
2022-11-23 12:53:16 -08:00
RTCDateTime convertRtcDateTimeFromEfi ( efidatetime_t const * const dateTime ) {
2022-09-20 02:28:42 -07:00
RTCDateTime timespec ;
2022-11-23 12:53:16 -08:00
timespec . year = dateTime - > year - RTC_BASE_YEAR ; // ChibiOS year origin is e.g. 1980
timespec . month = dateTime - > month ; // [1..12]
timespec . day = dateTime - > day ; // [1..31]
timespec . millisecond = ( ( ( dateTime - > hour * 60 ) + dateTime - > minute ) * 60 + dateTime - > second ) * 1000 ; // ms since midnight
timespec . dayofweek = RTC_DAY_CATURDAY ; // CATURDAY: 0 ... ?
timespec . dstflag = 0 ; // 0 ... ?
return timespec ;
2017-03-21 11:58:14 -07:00
}
2022-11-23 12:53:16 -08:00
// TODO(nms): move to e.g. efitime ?
2024-08-28 17:51:43 -07:00
static void putTwoSymbolDecimal ( int offset , char * destination , int value ) {
2016-08-09 21:04:24 -07:00
static char buff [ _MAX_FILLER ] ;
2023-04-11 17:01:34 -07:00
efiAssertVoid ( ObdCode : : CUSTOM_ERR_6666 , value > = 0 & & value < 100 , " value " ) ;
2016-08-08 21:03:08 -07:00
itoa10 ( buff , value ) ;
if ( value < 10 ) {
2024-08-28 17:51:43 -07:00
destination [ offset ] = ' 0 ' ;
destination [ offset + 1 ] = buff [ 0 ] ;
2016-08-08 21:03:08 -07:00
} else {
2024-08-28 17:51:43 -07:00
destination [ offset ] = buff [ 0 ] ;
destination [ offset + 1 ] = buff [ 1 ] ;
2016-08-08 21:03:08 -07:00
}
}
2022-11-23 12:53:16 -08:00
# endif // EFI_RTC
2016-08-08 21:03:08 -07:00
2017-08-22 21:46:34 -07:00
/**
* @ return true if we seem to know current date , false if no valid RTC state
*/
2024-08-28 17:51:43 -07:00
bool dateToStringShort ( char * destination ) {
2022-11-23 12:53:16 -08:00
# if EFI_RTC
2024-08-28 17:51:43 -07:00
strcpy ( destination , " 000000_000000 \0 " ) ;
2022-11-23 12:53:16 -08:00
efidatetime_t dateTime = getRtcDateTime ( ) ;
if ( dateTime . year < 2016 | | dateTime . year > 2030 ) {
2016-08-08 21:03:08 -07:00
// 2016 to 2030 is the valid range
2024-08-28 17:51:43 -07:00
destination [ 0 ] = 0 ;
2016-08-08 21:03:08 -07:00
return false ;
}
2020-05-17 14:02:22 -07:00
2024-08-28 17:51:43 -07:00
putTwoSymbolDecimal ( 0 , destination , dateTime . year % 100 ) ; // year, format as just the last two digits
putTwoSymbolDecimal ( 2 , destination , dateTime . month ) ; // month 1-12
putTwoSymbolDecimal ( 4 , destination , dateTime . day ) ; // day of the month 1-31
2020-05-17 14:02:22 -07:00
2024-08-28 17:51:43 -07:00
putTwoSymbolDecimal ( 7 , destination , dateTime . hour ) ; // hours since midnight 0-23
putTwoSymbolDecimal ( 9 , destination , dateTime . minute ) ; // minutes
putTwoSymbolDecimal ( 11 , destination , dateTime . second ) ; // seconds
2016-08-08 21:03:08 -07:00
return true ;
2022-11-23 12:53:16 -08:00
# else // EFI_RTC
2024-08-28 17:51:43 -07:00
destination [ 0 ] = 0 ;
2022-11-23 12:53:16 -08:00
return false ;
# endif // EFI_RTC
2016-08-08 21:03:08 -07:00
}
2024-08-28 17:51:43 -07:00
/*
void dateToString ( char * destination ) {
2022-11-23 12:53:16 -08: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
2024-08-28 17:51:43 -07:00
strcpy ( destination , " 00/00 00:00:00 \0 " ) ;
2022-11-23 12:53:16 -08:00
efidatetime_t dateTime = getRtcDateTime ( ) ;
2024-08-28 17:51:43 -07:00
putTwoSymbolDecimal ( 0 , destination , dateTime . month ) ;
putTwoSymbolDecimal ( 3 , destination , dateTime . day ) ;
putTwoSymbolDecimal ( 6 , destination , dateTime . hour ) ;
putTwoSymbolDecimal ( 9 , destination , dateTime . minute ) ;
putTwoSymbolDecimal ( 12 , destination , dateTime . second ) ;
2022-11-09 03:56:42 -08:00
# else // EFI_RTC
2024-08-28 17:51:43 -07:00
destination [ 0 ] = 0 ;
2022-11-09 03:56:42 -08:00
# endif // EFI_RTC
2015-07-10 06:01:56 -07:00
}
2024-08-28 17:51:43 -07:00
*/