11// clang-format off
22#include "u_nx_ethernet.h"
33#include "nx_stm32_eth_driver.h"
4+ #include "nxd_ptp_client.h"
45#include "u_nx_debug.h"
56#include "u_tx_debug.h"
67#include "nx_api.h"
1516#define _IP_THREAD_PRIORITY 1
1617#define _IP_NETWORK_MASK IP_ADDRESS(255, 255, 255, 0)
1718#define _UDP_QUEUE_MAXIMUM 12
19+ #define _PTP_THREAD_PRIORITY 2
1820
1921/* DEVICE INFO */
2022typedef struct {
2123 /* NetX Objects */
2224 NX_UDP_SOCKET socket ;
2325 NX_PACKET_POOL packet_pool ;
2426 NX_IP ip ;
27+ NX_PTP_CLIENT ptp_client ;
28+ SHORT ptp_utc_offset ;
2529
2630 /* Static memory for NetX stuff */
2731 UCHAR packet_pool_memory [_PACKET_POOL_SIZE ];
2832 UCHAR ip_memory [_IP_THREAD_STACK_SIZE ];
2933 UCHAR arp_cache_memory [_ARP_CACHE_SIZE ];
34+ ULONG ptp_stack [2048 / sizeof (ULONG )];
3035
3136 /* Device config variables */
3237 bool is_initialized ;
@@ -37,6 +42,45 @@ typedef struct {
3742} _ethernet_device_t ;
3843static _ethernet_device_t device = { 0 };
3944
45+ /* Callback function. Called when a PTP event is processed. */
46+ // extern UINT ptp_clock_callback(NX_PTP_CLIENT *client_ptr, UINT operation,
47+ // NX_PTP_TIME *time_ptr, NX_PACKET *packet_ptr,
48+ // VOID *callback_data);
49+
50+ /* Callback function. Called when a PTP event is processed. */
51+ static UINT _ptp_event_callback (NX_PTP_CLIENT * ptp_client_ptr , UINT event , VOID * event_data , VOID * callback_data )
52+ {
53+ NX_PARAMETER_NOT_USED (callback_data );
54+
55+ switch (event )
56+ {
57+ case NX_PTP_CLIENT_EVENT_MASTER :
58+ {
59+ PRINTLN_WARNING ("new MASTER clock!" );
60+ break ;
61+ }
62+
63+ case NX_PTP_CLIENT_EVENT_SYNC :
64+ {
65+ nx_ptp_client_sync_info_get ((NX_PTP_CLIENT_SYNC * )event_data , NX_NULL , & device .ptp_utc_offset );
66+ PRINTLN_INFO ("SYNC event: utc offset=%d" , device .ptp_utc_offset );
67+ break ;
68+ }
69+
70+ case NX_PTP_CLIENT_EVENT_TIMEOUT :
71+ {
72+ PRINTLN_WARNING ("Master clock TIMEOUT!" );
73+ break ;
74+ }
75+ default :
76+ {
77+ break ;
78+ }
79+ }
80+
81+ return 0 ;
82+ }
83+
4084/* Callback function. Called when an ethernet message is received. */
4185static void _receive_message (NX_UDP_SOCKET * socket ) {
4286 NX_PACKET * packet ;
@@ -92,8 +136,9 @@ static void _receive_message(NX_UDP_SOCKET *socket) {
92136/* API FUNCTIONS */
93137
94138uint8_t ethernet_init (ethernet_node_t node_id , DriverFunction driver , OnRecieve on_recieve ) {
95-
139+
96140 uint8_t status ;
141+ device .ptp_utc_offset = 0 ; // no offset to start
97142
98143 /* Make sure device isn't already initialized */
99144 if (device .is_initialized ) {
@@ -162,11 +207,11 @@ uint8_t ethernet_init(ethernet_node_t node_id, DriverFunction driver, OnRecieve
162207 return status ;
163208 }
164209
165- /* Set up multicast groups.
210+ /* Set up multicast groups.
166211 * (This iterates through every possible node combination between 0b00000001 and 0b11111111.
167212 * If any of the combinations include device.node_id, that combination gets added as a multicast group.
168213 * This ensures that ethernet messages can be sent to all possible combinations of recipients.)
169- *
214+ *
170215 * Note: This is probably pretty inefficient. I did it so you don't have to manually set up
171216 * multicast groups any time you want to send a message to a new combination of nodes,
172217 * but if this setup ends up being too slow or something, feel free to get rid of it.
@@ -181,6 +226,22 @@ uint8_t ethernet_init(ethernet_node_t node_id, DriverFunction driver, OnRecieve
181226 }
182227 }
183228
229+ /* Create the PTP client instance */
230+ status = nx_ptp_client_create (& device .ptp_client , & device .ip , 0 , & device .packet_pool ,
231+ _PTP_THREAD_PRIORITY , (UCHAR * )& device .ptp_stack , sizeof (device .ptp_stack ),
232+ _nx_ptp_client_soft_clock_callback , NX_NULL );
233+ if (status != NX_SUCCESS ) {
234+ PRINTLN_ERROR ("Failed to create PTP client (Status: %d/%s)." , status , nx_status_toString (status ));
235+ return status ;
236+ }
237+
238+ /* start the PTP client */
239+ status = nx_ptp_client_start (& device .ptp_client , NX_NULL , 0 , 0 , NX_PTP_TRANSPORT_SPECIFIC_NON_802 , _ptp_event_callback , NX_NULL );
240+ if (status != NX_SUCCESS ) {
241+ PRINTLN_ERROR ("Failed to start PTP client (Status: %d/%s)." , status , nx_status_toString (status ));
242+ return status ;
243+ }
244+
184245 /* Create UDP socket for broadcasting */
185246 status = nx_udp_socket_create (
186247 & device .ip , // IP instance
@@ -330,7 +391,19 @@ uint8_t ethernet_send_message(ethernet_message_t *message) {
330391 PRINTLN_INFO ("got to nx_udp_socket_send() part of send message" );
331392
332393 PRINTLN_INFO ("Sent ethernet message (Recipient ID: %d, Message ID: %d, Message Contents: %d)." , message -> recipient_id , message -> message_id , message -> data );
333- PRINTLN_INFO ("TX complete count: %lu" , tx_complete_count );
334394 return U_SUCCESS ;
335395}
336- // clang-format on
396+
397+ NX_PTP_DATE_TIME ethernet_get_time (void ) {
398+ NX_PTP_TIME tm ;
399+ NX_PTP_DATE_TIME date ;
400+ /* read the PTP clock */
401+ nx_ptp_client_time_get (& device .ptp_client , & tm );
402+
403+ /* convert PTP time to UTC date and time */
404+ nx_ptp_client_utility_convert_time_to_date (& tm , 0 , & date );
405+
406+ return date ;
407+ }
408+
409+ // clang-format on
0 commit comments