1+ #include "nxd_ptp_client.h"
12#include "rtc.h"
23#include <stdio.h>
34#include "stm32h5xx_hal.h"
5+ #include "u_tx_debug.h"
6+ #include <time.h>
47
58#define PTP_UTC_OFFSET 0 // UTC 0
69extern RTC_HandleTypeDef hrtc ;
710
8- NX_PTP_TIME * ptp_time ;
9- NX_PTP_DATE_TIME * ptp_date_time ;
10-
11- UINT interrupt_save ;
11+ UINT interrupt_save ; // do not remove
1212
1313static UINT us_to_second_ticks (ULONG us , UINT second_fractions )
1414{
@@ -21,138 +21,108 @@ static ULONG second_ticks_to_us(UINT second_ticks, UINT second_fractions)
2121 return (uint64_t )1000000L * second_ticks / (second_fractions + 1 );
2222}
2323
24- static void set_subsecond (UINT rtc_sub_second_tick , UINT second_fractions )
24+ static void set_subsecond (UINT rtc_sub_second_tick , UINT second_fractions , NX_PTP_DATE_TIME * current_time )
2525{
26- if (~( rtc_sub_second_tick >> 15 & 1 ) ) {
27- printf ("rtc SS overflow ig " );
26+ if (rtc_sub_second_tick > second_fractions ) {
27+ PRINTLN_ERROR ("rtc SS overflow" );
2828 }
2929
3030 UINT rtp_sub_second_tick = us_to_second_ticks (
31- ptp_date_time -> nanosecond / 1000 , second_fractions );
31+ current_time -> nanosecond / 1000 , second_fractions );
3232
3333 UINT offset_tick = 0 ; // ticks to go backwards
3434 UINT offset_ahead_1s = RTC_SHIFTADD1S_RESET ;
3535 if (rtc_sub_second_tick >= rtp_sub_second_tick ) { // local ahead
3636 offset_tick = rtc_sub_second_tick - rtp_sub_second_tick ;
3737 } else { // local behind
3838 offset_ahead_1s = RTC_SHIFTADD1S_SET ;
39- offset_tick = second_fractions -
40- ( rtc_sub_second_tick - rtp_sub_second_tick ) ;
39+ UINT delta = rtp_sub_second_tick - rtc_sub_second_tick ;
40+ offset_tick = ( second_fractions + 1 ) - delta ;
4141 }
4242 HAL_RTCEx_SetSynchroShift (& hrtc , offset_tick , offset_ahead_1s );
4343}
4444
45- static LONG diff_ptp_date_time (NX_PTP_DATE_TIME * time1 , NX_PTP_DATE_TIME * time2 )
46- {
47- #define SECS_PER_MINUTE 60
48- #define SECS_PER_HOUR (60 * SECS_PER_MINUTE)
49- #define SECS_PER_DAY (24 * SECS_PER_HOUR)
50- #define SECS_PER_YEAR (365 * SECS_PER_DAY)
51-
52- int64_t seconds_diff = 0 ;
53-
54- seconds_diff += (time2 -> year - time1 -> year ) * SECS_PER_YEAR ;
55- seconds_diff += (time2 -> day - time1 -> day ) * SECS_PER_DAY ;
56- seconds_diff += (time2 -> hour - time1 -> hour ) * SECS_PER_HOUR ;
57- seconds_diff += (time2 -> minute - time1 -> minute ) * SECS_PER_MINUTE ;
58- seconds_diff += (time2 -> second - time1 -> second ) * 1 ;
59-
60- return seconds_diff ;
61- }
62-
6345UINT nx_ptp_client_hard_clock_callback (NX_PTP_CLIENT * client_ptr ,
6446 UINT operation , NX_PTP_TIME * time_ptr ,
6547 NX_PACKET * packet_ptr ,
6648 VOID * callback_data )
6749{
50+ NX_PTP_DATE_TIME * current_date_time ;
51+ RTC_TimeTypeDef rtc_time = {0 };
52+ RTC_DateTypeDef rtc_date = {0 };
53+
6854 switch (operation ) {
6955 case NX_PTP_CLIENT_CLOCK_INIT :
7056 break ;
7157
7258 case NX_PTP_CLIENT_CLOCK_SET :
7359 TX_DISABLE
7460
75- ptp_time = time_ptr ;
76-
7761 nx_ptp_client_utility_convert_time_to_date (
78- ptp_time , - PTP_UTC_OFFSET , ptp_date_time );
62+ time_ptr , - PTP_UTC_OFFSET , current_date_time );
7963
80- RTC_TimeTypeDef rtp_time = {
81- .Hours = ptp_date_time -> hour ,
82- .Minutes = ptp_date_time -> minute ,
83- .Seconds = ptp_date_time -> second ,
64+ rtc_time = ( RTC_TimeTypeDef ) {
65+ .Hours = current_date_time -> hour ,
66+ .Minutes = current_date_time -> minute ,
67+ .Seconds = current_date_time -> second ,
8468 .TimeFormat = 0 ,
8569 };
8670
87- RTC_DateTypeDef rtp_date = {
88- .Year = ptp_date_time -> year ,
89- .Month = ptp_date_time -> month ,
90- .Date = ptp_date_time -> day ,
91- .WeekDay = ptp_date_time -> weekday ,
71+ rtc_date = ( RTC_DateTypeDef ) {
72+ .Year = current_date_time -> year % 100 ,
73+ .Month = current_date_time -> month ,
74+ .Date = current_date_time -> day ,
75+ .WeekDay = current_date_time -> weekday ,
9276 };
9377
94- // NOTE: 24 hours RTC assumed.
95- RTC_TimeTypeDef rtc_sub_seconds = {};
96-
97- HAL_RTC_GetTime (& hrtc , & rtc_sub_seconds ,
98- RTC_FORMAT_BCD );
99-
100- HAL_RTC_SetTime (& hrtc , & rtp_time , RTC_FORMAT_BCD );
101-
102- HAL_RTC_SetDate (& hrtc , & rtp_date , RTC_FORMAT_BCD );
103-
104- set_subsecond (rtc_sub_seconds .SecondFraction -
105- rtc_sub_seconds .SubSeconds ,
106- rtc_sub_seconds .SubSeconds );
78+ HAL_RTC_SetTime (& hrtc , & rtc_time , RTC_FORMAT_BIN );
79+ HAL_RTC_SetDate (& hrtc , & rtc_date , RTC_FORMAT_BIN );
80+
81+ // After SetTime, SubSeconds is reset to SecondFraction (0 elapsed).
82+ // Shift from 0 elapsed ticks to wherever PTP nanosecond says we should be.
83+ RTC_TimeTypeDef after_set = {};
84+ HAL_RTC_GetTime (& hrtc , & after_set , RTC_FORMAT_BIN ); // to get a valid SecondFraction
85+ set_subsecond (0 , after_set .SecondFraction , current_date_time );
86+
87+ // dummy get date
88+ HAL_RTC_GetDate (& hrtc , & rtc_date , RTC_FORMAT_BIN );
10789 TX_RESTORE
90+ break ;
10891 case NX_PTP_CLIENT_CLOCK_PACKET_TS_EXTRACT : // FALL THROUGH
10992 case NX_PTP_CLIENT_CLOCK_GET :
11093 TX_DISABLE
111- RTC_TimeTypeDef rtc_time = {};
112- RTC_DateTypeDef rtc_date = {};
11394
114- HAL_RTC_GetTime (& hrtc , & rtc_time , RTC_FORMAT_BCD );
115- HAL_RTCEx_GetTimeStamp (& hrtc , & rtc_time , & rtc_date ,
116- RTC_FORMAT_BCD );
95+ HAL_RTC_GetTime (& hrtc , & rtc_time , RTC_FORMAT_BIN );
96+ HAL_RTC_GetDate (& hrtc , & rtc_date , RTC_FORMAT_BIN );
11797
11898 NX_PTP_DATE_TIME rtc_ptp_date_time = {
119- .year = rtp_date .Year ,
120- .month = rtp_date .Month ,
121- .weekday = rtp_date .WeekDay ,
122- .day = rtp_date .Date ,
99+ .year = rtc_date .Year ,
100+ .month = rtc_date .Month ,
101+ .weekday = rtc_date .WeekDay ,
102+ .day = rtc_date .Date ,
123103 .hour = rtc_time .Hours ,
124104 .minute = rtc_time .Minutes ,
125105 .second = rtc_time .Seconds ,
126106 .nanosecond =
127107 1000 * second_ticks_to_us (
128- rtc_time . SubSeconds ,
129- rtc_time .SecondFraction )
108+ rtc_time . SecondFraction - rtc_time . SubSeconds ,
109+ rtc_time .SecondFraction )
130110 };
131111
132- int64_t secondsDiff = diff_ptp_date_time (
133- ptp_date_time , & rtc_ptp_date_time );
112+ // helpful way to get UNIX time from RTC so we can give it to NetX layer
113+ time_t current_time_unix = { 0 };
114+ struct tm tim = {0 };
115+ tim .tm_year = rtc_date .Year + 100 ;
116+ tim .tm_mon = rtc_date .Month - 1 ;
117+ tim .tm_mday = rtc_date .Date ;
118+ tim .tm_hour = rtc_time .Hours ;
119+ tim .tm_min = rtc_time .Minutes ;
120+ tim .tm_sec = rtc_time .Seconds ;
121+ current_time_unix = mktime (& tim );
134122
135- NX_PTP_TIME current_ptp_time = {
136- .second_high = ptp_time -> second_high ,
137- .second_low = ptp_time -> second_low ,
138- .nanosecond = 0
139- };
140123
141- if (secondsDiff >
142- 0 ) { // ahead of previous ptp time stamp
143- _nx_ptp_client_utility_add64 (
144- & current_ptp_time .second_high ,
145- & current_ptp_time .second_low , 0 ,
146- secondsDiff );
147- } else {
148- _nx_ptp_client_utility_sub64 (
149- & current_ptp_time .second_high ,
150- & current_ptp_time .second_low , 0 ,
151- secondsDiff );
152- }
153-
154- time_ptr -> second_high = current_ptp_time .second_high ;
155- time_ptr -> second_low = current_ptp_time .second_low ;
124+ time_ptr -> second_high = 0 ; // todo fix by 2038
125+ time_ptr -> second_low = (ULONG ) current_time_unix ;
156126 time_ptr -> nanosecond =
157127 rtc_ptp_date_time
158128 .nanosecond ; // pull directly from rtc
@@ -161,29 +131,31 @@ UINT nx_ptp_client_hard_clock_callback(NX_PTP_CLIENT *client_ptr,
161131 break ;
162132 case NX_PTP_CLIENT_CLOCK_ADJUST :
163133 TX_DISABLE
164- ptp_time = time_ptr ;
165134
166135 nx_ptp_client_utility_convert_time_to_date (
167- ptp_time , - PTP_UTC_OFFSET , ptp_date_time );
136+ time_ptr , - PTP_UTC_OFFSET , current_date_time );
168137
169- HAL_RTC_GetTime (& hrtc , & rtc_time , RTC_FORMAT_BCD );
138+ HAL_RTC_GetTime (& hrtc , & rtc_time , RTC_FORMAT_BIN );
170139
171140 set_subsecond (
172141 rtc_time .SecondFraction - rtc_time .SubSeconds ,
173- rtc_time .SubSeconds ); // (between 0 and PREDIV_S (aka SecondFraction), counting up)
142+ rtc_time .SecondFraction , current_date_time ); // (between 0 and PREDIV_S (aka SecondFraction), counting up)
174143
175144 TX_RESTORE
145+
146+ // dummy get date
147+ HAL_RTC_GetDate (& hrtc , & rtc_date , RTC_FORMAT_BIN );
176148 break ;
177149 case NX_PTP_CLIENT_CLOCK_PACKET_TS_PREPARE :
178150 nx_ptp_client_packet_timestamp_notify (
179- client_ptr , packet_ptr , ptp_time );
151+ client_ptr , packet_ptr , time_ptr ); // this is probably wrong, instead we need to fetch the time via RTC
180152 break ;
181153 case NX_PTP_CLIENT_CLOCK_SOFT_TIMER_UPDATE : // do nothing
182154 break ;
183155 default :
184- printf ("How Did We Get Here? (rtc.h)" );
156+ PRINTLN_ERROR ("How Did We Get Here? (rtc.h)" );
185157 break ;
186158 }
187159
188160 return NX_SUCCESS ;
189- }
161+ }
0 commit comments