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
efiPrintf ( " Current RTC time: %02u %s %04u %02u:%02u:%02u " ,
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
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 ?
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 ] ;
}
}
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
*/
2016-08-08 21:03:08 -07:00
bool dateToStringShort ( char * lcd_str ) {
2022-11-23 12:53:16 -08:00
# if EFI_RTC
2020-05-17 14:02:22 -07:00
strcpy ( lcd_str , " 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
lcd_str [ 0 ] = 0 ;
return false ;
}
2020-05-17 14:02:22 -07:00
2022-11-23 12:53:16 -08:00
put2 ( 0 , lcd_str , dateTime . year % 100 ) ; // year, format as just the last two digits
put2 ( 2 , lcd_str , dateTime . month ) ; // month 1-12
put2 ( 4 , lcd_str , dateTime . day ) ; // day of the month 1-31
2020-05-17 14:02:22 -07:00
2022-11-23 12:53:16 -08:00
put2 ( 7 , lcd_str , dateTime . hour ) ; // hours since midnight 0-23
put2 ( 9 , lcd_str , dateTime . minute ) ; // minutes
put2 ( 11 , lcd_str , dateTime . second ) ; // seconds
2016-08-08 21:03:08 -07:00
return true ;
2022-11-23 12:53:16 -08:00
# else // EFI_RTC
lcd_str [ 0 ] = 0 ;
return false ;
# endif // EFI_RTC
2016-08-08 21:03:08 -07:00
}
2015-07-10 06:01:56 -07:00
void dateToString ( char * lcd_str ) {
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
strcpy ( lcd_str , " 00/00 00:00:00 \0 " ) ;
2022-11-23 12:53:16 -08:00
efidatetime_t dateTime = getRtcDateTime ( ) ;
2015-07-10 06:01:56 -07:00
2022-11-23 12:53:16 -08:00
put2 ( 0 , lcd_str , dateTime . month ) ;
put2 ( 3 , lcd_str , dateTime . day ) ;
put2 ( 6 , lcd_str , dateTime . hour ) ;
put2 ( 9 , lcd_str , dateTime . minute ) ;
put2 ( 12 , lcd_str , dateTime . second ) ;
2022-11-09 03:56:42 -08:00
# else // EFI_RTC
2021-05-04 15:55:27 -07:00
lcd_str [ 0 ] = 0 ;
2022-11-09 03:56:42 -08:00
# endif // EFI_RTC
2015-07-10 06:01:56 -07:00
}