1 /*
2 This is a small demo of the NetX Duo PTP client on the high-performance NetX Duo TCP/IP stack.
3 This demo relies on ThreadX, NetX Duo and NetX Duo PTP client API to execute the Precision Time
4 Protocol.
5
6 */
7
8 #include <stdio.h>
9 #include "nx_api.h"
10 #include "nxd_ptp_client.h"
11
12 #ifndef SAMPLE_DHCP_DISABLE
13 #include "nxd_dhcp_client.h"
14 #endif /* SAMPLE_DHCP_DISABLE */
15
16 #define PTP_THREAD_PRIORITY 2
17
18 /* Define the ThreadX and NetX object control blocks... */
19 static TX_THREAD thread_0;
20 static NX_PACKET_POOL pool_0;
21 static NX_IP ip_0;
22 #ifndef SAMPLE_DHCP_DISABLE
23 static NX_DHCP dhcp_client;
24 #endif /* SAMPLE_DHCP_DISABLE */
25 static NX_PTP_CLIENT ptp_client;
26
27 /* Define the IP thread's stack area. */
28 static ULONG ip_thread_stack[2048 / sizeof(ULONG)];
29
30 /* Define packet pool for the demonstration. */
31 static ULONG packet_pool_area[((1536 + sizeof(NX_PACKET)) * 32) / sizeof(ULONG)];
32
33 /* Define the ARP cache area. */
34 static ULONG arp_space_area[512 / sizeof(ULONG)];
35
36 /* Define the main thread. */
37 static ULONG thread_0_stack[2048 / sizeof(ULONG)];
38 static ULONG ptp_stack[2048 / sizeof(ULONG)];
39
40 /* Define an error counter. */
41 static ULONG error_counter;
42
43 /* Define ptp utc offset. */
44 static SHORT ptp_utc_offset = 0;
45
46 #ifndef SAMPLE_DHCP_DISABLE
47 #define IPV4_ADDRESS IP_ADDRESS(0, 0, 0, 0)
48 #define IPV4_NETWORK_MASK IP_ADDRESS(0, 0, 0, 0)
49 #else
50 #define IPV4_ADDRESS IP_ADDRESS(10, 1, 0, 212)
51 #define IPV4_NETWORK_MASK IP_ADDRESS(255, 255, 0, 0)
52 #define IPV4_GATEWAY_ADDR IP_ADDRESS(10, 1, 0, 1)
53 #define DNS_SERVER_ADDRESS IP_ADDRESS(10, 1, 0, 1)
54 #endif /* SAMPLE_DHCP_DISABLE */
55
56 /* Define the main thread entry point. */
57 static VOID thread_0_entry(ULONG thread_input);
58
59 /* PTP handler. */
60 static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data);
61
62 #ifndef SAMPLE_DHCP_DISABLE
63 static void dhcp_wait();
64 #endif /* SAMPLE_DHCP_DISABLE */
65
66 /***** Substitute your ethernet driver entry function here *********/
67 #ifndef NETWORK_DRIVER
68 #define NETWORK_DRIVER _nx_ram_network_driver
69 #endif
70 extern VOID NETWORK_DRIVER(NX_IP_DRIVER *driver_req_ptr);
71
72 #ifndef CLOCK_CALLBACK
73 #define CLOCK_CALLBACK nx_ptp_client_soft_clock_callback
74 #endif
75 extern UINT CLOCK_CALLBACK(NX_PTP_CLIENT *client_ptr, UINT operation,
76 NX_PTP_TIME *time_ptr, NX_PACKET *packet_ptr,
77 VOID *callback_data);
78
79 #ifdef HARDWARE_SETUP
80 extern VOID HARDWARE_SETUP();
81 #endif
82
main()83 int main()
84 {
85 #ifdef HARDWARE_SETUP
86 HARDWARE_SETUP();
87 #endif
88
89 /* Enter the ThreadX kernel. */
90 tx_kernel_enter();
91 return 0;
92 }
93
94
95 /* Define what the initial system looks like. */
96
tx_application_define(void * first_unused_memory)97 void tx_application_define(void *first_unused_memory)
98 {
99
100 UINT status;
101
102
103 /* Initialize the NetX system. */
104 nx_system_initialize();
105
106 /* Create a packet pool. */
107 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, (ULONG*)(((int)packet_pool_area + 15) & ~15) , sizeof(packet_pool_area));
108
109 /* Check for pool creation error. */
110 if (status)
111 error_counter++;
112
113 /* Create an IP instance. */
114 status = nx_ip_create(&ip_0,
115 "NetX IP Instance 0",
116 IPV4_ADDRESS,
117 IPV4_NETWORK_MASK,
118 &pool_0,
119 NETWORK_DRIVER,
120 (UCHAR*)ip_thread_stack,
121 sizeof(ip_thread_stack),
122 1);
123
124 /* Check for IP create errors. */
125 if (status)
126 error_counter++;
127
128 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
129 status = nx_arp_enable(&ip_0, (void *)arp_space_area, sizeof(arp_space_area));
130
131 /* Check for ARP enable errors. */
132 if (status)
133 error_counter++;
134
135 /* Enable TCP traffic. */
136 status = nx_tcp_enable(&ip_0);
137
138 /* Check for TCP enable errors. */
139 if (status)
140 error_counter++;
141
142 /* Enable UDP traffic. */
143 status = nx_udp_enable(&ip_0);
144
145 /* Check for UDP enable errors. */
146 if (status)
147 error_counter++;
148
149 /* Enable ICMP. */
150 status = nx_icmp_enable(&ip_0);
151
152 /* Check for errors. */
153 if (status)
154 error_counter++;
155
156 /* Create the main thread. */
157 tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
158 thread_0_stack, sizeof(thread_0_stack),
159 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
160 }
161
162
163 /* Define the test threads. */
thread_0_entry(ULONG thread_input)164 void thread_0_entry(ULONG thread_input)
165 {
166
167 NX_PTP_TIME tm;
168 NX_PTP_DATE_TIME date;
169
170 #ifndef SAMPLE_DHCP_DISABLE
171 dhcp_wait();
172 #endif /* SAMPLE_DHCP_DISABLE */
173
174 /* Create the PTP client instance */
175 nx_ptp_client_create(&ptp_client, &ip_0, 0, &pool_0,
176 PTP_THREAD_PRIORITY, (UCHAR *)ptp_stack, sizeof(ptp_stack),
177 CLOCK_CALLBACK, NX_NULL);
178
179 /* start the PTP client */
180 nx_ptp_client_start(&ptp_client, NX_NULL, 0, 0, 0, ptp_event_callback, NX_NULL);
181
182 while(1)
183 {
184
185 /* read the PTP clock */
186 nx_ptp_client_time_get(&ptp_client, &tm);
187
188 /* convert PTP time to UTC date and time */
189 nx_ptp_client_utility_convert_time_to_date(&tm, -ptp_utc_offset, &date);
190
191 /* display the current time */
192 printf("%2u/%02u/%u %02u:%02u:%02u.%09lu\r\n", date.day, date.month, date.year, date.hour, date.minute, date.second, date.nanosecond);
193
194 tx_thread_sleep(NX_IP_PERIODIC_RATE);
195 }
196 }
197
ptp_event_callback(NX_PTP_CLIENT * ptp_client_ptr,UINT event,VOID * event_data,VOID * callback_data)198 static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data)
199 {
200 NX_PARAMETER_NOT_USED(callback_data);
201
202 switch (event)
203 {
204 case NX_PTP_CLIENT_EVENT_MASTER:
205 {
206 printf("new MASTER clock!\r\n");
207 break;
208 }
209
210 case NX_PTP_CLIENT_EVENT_SYNC:
211 {
212 nx_ptp_client_sync_info_get((NX_PTP_CLIENT_SYNC *)event_data, NX_NULL, &ptp_utc_offset);
213 printf("SYNC event: utc offset=%d\r\n", ptp_utc_offset);
214 break;
215 }
216
217 case NX_PTP_CLIENT_EVENT_TIMEOUT:
218 {
219 printf("Master clock TIMEOUT!\r\n");
220 break;
221 }
222 default:
223 {
224 break;
225 }
226 }
227
228 return 0;
229 }
230
231 /* DHCP */
232 #ifndef SAMPLE_DHCP_DISABLE
dhcp_wait(void)233 void dhcp_wait(void)
234 {
235
236 ULONG actual_status;
237 ULONG ip_address;
238 ULONG network_mask;
239 ULONG gw_address;
240
241 printf("DHCP In Progress...\r\n");
242
243 /* Create the DHCP instance. */
244 nx_dhcp_create(&dhcp_client, &ip_0, "dhcp_client");
245
246 /* Start the DHCP Client. */
247 nx_dhcp_start(&dhcp_client);
248
249 /* Wait util address is solved. */
250 nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &actual_status, NX_WAIT_FOREVER);
251
252 /* Get IP address. */
253 nx_ip_address_get(&ip_0, &ip_address, &network_mask);
254 nx_ip_gateway_address_get(&ip_0, &gw_address);
255
256 /* Output IP address. */
257 printf("IP address: %d.%d.%d.%d\r\nMask: %d.%d.%d.%d\r\nGateway: %d.%d.%d.%d\r\n",
258 (INT)(ip_address >> 24),
259 (INT)(ip_address >> 16 & 0xFF),
260 (INT)(ip_address >> 8 & 0xFF),
261 (INT)(ip_address & 0xFF),
262 (INT)(network_mask >> 24),
263 (INT)(network_mask >> 16 & 0xFF),
264 (INT)(network_mask >> 8 & 0xFF),
265 (INT)(network_mask & 0xFF),
266 (INT)(gw_address >> 24),
267 (INT)(gw_address >> 16 & 0xFF),
268 (INT)(gw_address >> 8 & 0xFF),
269 (INT)(gw_address & 0xFF));
270 }
271 #endif /* SAMPLE_DHCP_DISABLE */