99#define SCREEN_SIZE_X 128
1010#define SCREEN_SIZE_Y 64
1111#define DCF77_FREQ 77500
12- #define DCF77_OFFSET 61
12+ #define DCF77_OFFSET 60
1313#define SYNC_DELAY 50
1414#define UPDATES 8
1515
16+ #define SECONDS_PER_MINUTE 60
17+ #define SECONDS_PER_HOUR (SECONDS_PER_MINUTE * 60)
18+ #define SECONDS_PER_DAY (SECONDS_PER_HOUR * 24)
19+ #define MONTHS_COUNT 12
20+ #define EPOCH_START_YEAR 1970
21+
1622char * WEEKDAYS [] = {"Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" , "Sun" };
1723
1824typedef struct {
1925 FuriHalRtcDateTime dt ;
26+ FuriHalRtcDateTime dcf_dt ;
2027 bool is_dst ;
2128} AppData ;
2229
@@ -51,6 +58,34 @@ static void app_input_callback(InputEvent *input_event, void *ctx)
5158 furi_message_queue_put (event_queue , input_event , FuriWaitForever );
5259}
5360
61+ void time_add (FuriHalRtcDateTime * from , FuriHalRtcDateTime * to , int add )
62+ {
63+ uint32_t timestamp = furi_hal_rtc_datetime_to_timestamp (from ) + add ;
64+
65+ uint32_t days = timestamp / SECONDS_PER_DAY ;
66+ uint32_t seconds_in_day = timestamp % SECONDS_PER_DAY ;
67+
68+ to -> year = EPOCH_START_YEAR ;
69+
70+ while (days >= furi_hal_rtc_get_days_per_year (to -> year )) {
71+ days -= furi_hal_rtc_get_days_per_year (to -> year );
72+ (to -> year )++ ;
73+ }
74+
75+ to -> month = 1 ;
76+ while (days >= furi_hal_rtc_get_days_per_month (furi_hal_rtc_is_leap_year (to -> year ), to -> month )) {
77+ days -= furi_hal_rtc_get_days_per_month (furi_hal_rtc_is_leap_year (to -> year ), to -> month );
78+ (to -> month )++ ;
79+ }
80+
81+ to -> weekday = ((days + 4 ) % 7 ) + 1 ;
82+
83+ to -> day = days + 1 ;
84+ to -> hour = seconds_in_day / SECONDS_PER_HOUR ;
85+ to -> minute = (seconds_in_day % SECONDS_PER_HOUR ) / SECONDS_PER_MINUTE ;
86+ to -> second = seconds_in_day % SECONDS_PER_MINUTE ;
87+ }
88+
5489int dcf77_clock_sync_app_main (void * p )
5590{
5691 UNUSED (p );
@@ -60,7 +95,8 @@ int dcf77_clock_sync_app_main(void *p)
6095
6196 app_data .is_dst = false;
6297 furi_hal_rtc_get_datetime (& app_data .dt );
63- set_dcf77_time (& app_data .dt , app_data .is_dst );
98+ time_add (& app_data .dt , & app_data .dcf_dt , DCF77_OFFSET );
99+ set_dcf77_time (& app_data .dcf_dt , app_data .is_dst );
64100
65101 ViewPort * view_port = view_port_alloc ();
66102 FuriMessageQueue * event_queue = furi_message_queue_alloc (8 , sizeof (InputEvent ));
@@ -98,11 +134,8 @@ int dcf77_clock_sync_app_main(void *p)
98134 furi_hal_light_set (LightBlue , 0xFF );
99135 }
100136 else {
101- FuriHalRtcDateTime dcf_dt ; // next minute
102- furi_hal_rtc_timestamp_to_datetime (furi_hal_rtc_datetime_to_timestamp (& app_data .dt ) + DCF77_OFFSET , & dcf_dt );
103- // fix forgotten weekday
104- dcf_dt .weekday = (app_data .dt .day == dcf_dt .day ) ? app_data .dt .weekday : (app_data .dt .weekday % 7 ) + 1 ;
105- set_dcf77_time (& dcf_dt , app_data .is_dst );
137+ time_add (& app_data .dt , & app_data .dcf_dt , DCF77_OFFSET + 1 );
138+ set_dcf77_time (& app_data .dcf_dt , app_data .is_dst );
106139 }
107140
108141 sec = app_data .dt .second ;
0 commit comments