11// clang-format off
22#include "u_nx_ethernet.h"
3+ #include "nx_stm32_eth_driver.h"
4+ #include "nxd_ptp_client.h"
35#include "u_nx_debug.h"
46#include "u_tx_debug.h"
57#include "nx_api.h"
68#include <string.h>
79#include <stdio.h>
810
911/* PRIVATE MACROS */
10- #define _PACKET_POOL_SIZE \
11- ((sizeof(ethernet_message_t) + sizeof(NX_PACKET)) * ETH_MAX_PACKETS)
1212#define _IP_THREAD_STACK_SIZE 2048
1313#define _ARP_CACHE_SIZE 1024
1414#define _IP_THREAD_PRIORITY 1
1515#define _IP_NETWORK_MASK IP_ADDRESS(255, 255, 255, 0)
1616#define _UDP_QUEUE_MAXIMUM 12
17+ #define _PTP_THREAD_PRIORITY 2
18+
19+ /* The DEFAULT_PAYLOAD_SIZE should match with RxBuffLen configured via MX_ETH_Init */
20+ #define DEFAULT_PAYLOAD_SIZE 1524
21+ #define NX_APP_PACKET_POOL_SIZE ((DEFAULT_PAYLOAD_SIZE + sizeof(NX_PACKET)) * 10)
1722
1823/* DEVICE INFO */
1924typedef struct {
2025 /* NetX Objects */
2126 NX_UDP_SOCKET socket ;
2227 NX_PACKET_POOL packet_pool ;
2328 NX_IP ip ;
29+ NX_PTP_CLIENT ptp_client ;
30+ SHORT ptp_utc_offset ;
2431
2532 /* Static memory for NetX stuff */
26- UCHAR packet_pool_memory [_PACKET_POOL_SIZE ];
33+ UCHAR packet_pool_memory [NX_APP_PACKET_POOL_SIZE ];
2734 UCHAR ip_memory [_IP_THREAD_STACK_SIZE ];
2835 UCHAR arp_cache_memory [_ARP_CACHE_SIZE ];
36+ ULONG ptp_stack [2048 / sizeof (ULONG )];
2937
3038 /* Device config variables */
3139 bool is_initialized ;
@@ -36,6 +44,45 @@ typedef struct {
3644} _ethernet_device_t ;
3745static _ethernet_device_t device = { 0 };
3846
47+ /* Callback function. Called when a PTP event is processed. */
48+ // extern UINT ptp_clock_callback(NX_PTP_CLIENT *client_ptr, UINT operation,
49+ // NX_PTP_TIME *time_ptr, NX_PACKET *packet_ptr,
50+ // VOID *callback_data);
51+
52+ /* Callback function. Called when a PTP event is processed. */
53+ static UINT _ptp_event_callback (NX_PTP_CLIENT * ptp_client_ptr , UINT event , VOID * event_data , VOID * callback_data )
54+ {
55+ NX_PARAMETER_NOT_USED (callback_data );
56+
57+ switch (event )
58+ {
59+ case NX_PTP_CLIENT_EVENT_MASTER :
60+ {
61+ PRINTLN_WARNING ("new MASTER clock!" );
62+ break ;
63+ }
64+
65+ case NX_PTP_CLIENT_EVENT_SYNC :
66+ {
67+ nx_ptp_client_sync_info_get ((NX_PTP_CLIENT_SYNC * )event_data , NX_NULL , & device .ptp_utc_offset );
68+ PRINTLN_INFO ("SYNC event: utc offset=%d" , device .ptp_utc_offset );
69+ break ;
70+ }
71+
72+ case NX_PTP_CLIENT_EVENT_TIMEOUT :
73+ {
74+ PRINTLN_WARNING ("Master clock TIMEOUT!" );
75+ break ;
76+ }
77+ default :
78+ {
79+ break ;
80+ }
81+ }
82+
83+ return 0 ;
84+ }
85+
3986/* Callback function. Called when an ethernet message is received. */
4087static void _receive_message (NX_UDP_SOCKET * socket ) {
4188 NX_PACKET * packet ;
@@ -91,8 +138,9 @@ static void _receive_message(NX_UDP_SOCKET *socket) {
91138/* API FUNCTIONS */
92139
93140uint8_t ethernet_init (ethernet_node_t node_id , DriverFunction driver , OnRecieve on_recieve ) {
94-
141+
95142 uint8_t status ;
143+ device .ptp_utc_offset = 0 ; // no offset to start
96144
97145 /* Make sure device isn't already initialized */
98146 if (device .is_initialized ) {
@@ -109,9 +157,9 @@ uint8_t ethernet_init(ethernet_node_t node_id, DriverFunction driver, OnRecieve
109157 status = nx_packet_pool_create (
110158 & device .packet_pool , // Pointer to the packet pool instance
111159 "Ethernet Packet Pool" , // Name
112- sizeof ( ethernet_message_t ) , // Payload size (i.e. the size of each packet)
160+ DEFAULT_PAYLOAD_SIZE , // Payload size (i.e. the size of each packet)
113161 device .packet_pool_memory , // Pointer to the pool's memory area
114- _PACKET_POOL_SIZE // Size of the pool's memory area
162+ NX_APP_PACKET_POOL_SIZE // Size of the pool's memory area
115163 );
116164 if (status != NX_SUCCESS ) {
117165 PRINTLN_ERROR ("Failed to create packet pool (Status: %d/%s)." , status , nx_status_toString (status ));
@@ -161,11 +209,11 @@ uint8_t ethernet_init(ethernet_node_t node_id, DriverFunction driver, OnRecieve
161209 return status ;
162210 }
163211
164- /* Set up multicast groups.
212+ /* Set up multicast groups.
165213 * (This iterates through every possible node combination between 0b00000001 and 0b11111111.
166214 * If any of the combinations include device.node_id, that combination gets added as a multicast group.
167215 * This ensures that ethernet messages can be sent to all possible combinations of recipients.)
168- *
216+ *
169217 * Note: This is probably pretty inefficient. I did it so you don't have to manually set up
170218 * multicast groups any time you want to send a message to a new combination of nodes,
171219 * but if this setup ends up being too slow or something, feel free to get rid of it.
@@ -180,6 +228,22 @@ uint8_t ethernet_init(ethernet_node_t node_id, DriverFunction driver, OnRecieve
180228 }
181229 }
182230
231+ /* Create the PTP client instance */
232+ status = nx_ptp_client_create (& device .ptp_client , & device .ip , 0 , & device .packet_pool ,
233+ _PTP_THREAD_PRIORITY , (UCHAR * )& device .ptp_stack , sizeof (device .ptp_stack ),
234+ _nx_ptp_client_soft_clock_callback , NX_NULL );
235+ if (status != NX_SUCCESS ) {
236+ PRINTLN_ERROR ("Failed to create PTP client (Status: %d/%s)." , status , nx_status_toString (status ));
237+ return status ;
238+ }
239+
240+ /* start the PTP client */
241+ status = nx_ptp_client_start (& device .ptp_client , NX_NULL , 0 , 0 , 0 , _ptp_event_callback , NX_NULL );
242+ if (status != NX_SUCCESS ) {
243+ PRINTLN_ERROR ("Failed to start PTP client (Status: %d/%s)." , status , nx_status_toString (status ));
244+ return status ;
245+ }
246+
183247 /* Create UDP socket for broadcasting */
184248 status = nx_udp_socket_create (
185249 & device .ip , // IP instance
@@ -263,6 +327,18 @@ uint8_t ethernet_send_message(ethernet_message_t *message) {
263327 return U_ERROR ;
264328 }
265329
330+ PRINTLN_INFO ("got to this part of ethernet_send_message()" );
331+
332+ /* Make sure interface is up. */
333+ ULONG actual_status = 0 ;
334+ status = nx_ip_interface_status_check (& device .ip , 0 , NX_IP_LINK_ENABLED , & actual_status , 1000 );
335+ if (status != NX_SUCCESS ) {
336+ PRINTLN_ERROR ("Failed to call nx_ip_interface_status_check() (Status: %d/%s)." , status , nx_status_toString (status ));
337+ return U_ERROR ;
338+ } else {
339+ PRINTLN_INFO ("Succeeded calling nx_ip_interface_status_check() (Status: %d/%s)." , status , nx_status_toString (status ));
340+ }
341+
266342 /* Allocate a packet */
267343 status = nx_packet_allocate (
268344 & device .packet_pool , // Packet pool
@@ -275,6 +351,8 @@ uint8_t ethernet_send_message(ethernet_message_t *message) {
275351 return U_ERROR ;
276352 }
277353
354+ PRINTLN_INFO ("got to nx_packet_allocate() part of send message" );
355+
278356 /* Append message data to packet */
279357 status = nx_packet_data_append (
280358 packet , // Packet
@@ -289,6 +367,16 @@ uint8_t ethernet_send_message(ethernet_message_t *message) {
289367 return U_ERROR ;
290368 }
291369
370+ PRINTLN_INFO ("got to nx_packet_data_append() part of send message" );
371+
372+ ULONG length = 0 ;
373+ status = nx_packet_length_get (packet , & length );
374+ if (status != NX_SUCCESS ) {
375+ PRINTLN_ERROR ("Failed to call nx_packet_length_get() (Status: %d/%n)." , status , nx_status_toString (status ));
376+ } else {
377+ PRINTLN_INFO ("Packet has length of %d!" , length );
378+ }
379+
292380 /* Send message */
293381 status = nx_udp_socket_send (
294382 & device .socket ,
@@ -297,12 +385,27 @@ uint8_t ethernet_send_message(ethernet_message_t *message) {
297385 ETH_UDP_PORT
298386 );
299387 if (status != NX_SUCCESS ) {
300- PRINTLN_ERROR ("Failed to send packet (Status: %d/%s, Message ID: %d)." , status , nx_status_toString (status ), message -> message_id );
388+ PRINTLN_ERROR ("Failed to send packet (Status: %d/%s, Message ID: %d, Recipient ID: %d, IP Address: %d, IP components: 224.0.0.%d )." , status , nx_status_toString (status ), message -> message_id , message -> recipient_id , ETH_IP ( message -> recipient_id ), ETH_IP ( message -> recipient_id ) );
301389 nx_packet_release (packet );
302390 return U_ERROR ;
303391 }
304392
305- PRINTLN_INFO ("Sent ethernet message (Recipient ID: %d, Message ID: %d)." , message -> recipient_id , message -> message_id );
393+ PRINTLN_INFO ("got to nx_udp_socket_send() part of send message" );
394+
395+ PRINTLN_INFO ("Sent ethernet message (Recipient ID: %d, Message ID: %d, Message Contents: %d)." , message -> recipient_id , message -> message_id , message -> data );
306396 return U_SUCCESS ;
307397}
308- // clang-format on
398+
399+ NX_PTP_DATE_TIME ethernet_get_time (void ) {
400+ NX_PTP_TIME tm ;
401+ NX_PTP_DATE_TIME date ;
402+ /* read the PTP clock */
403+ nx_ptp_client_time_get (& device .ptp_client , & tm );
404+
405+ /* convert PTP time to UTC date and time */
406+ nx_ptp_client_utility_convert_time_to_date (& tm , 0 , & date );
407+
408+ return date ;
409+ }
410+
411+ // clang-format on
0 commit comments