]> begriffs open source - cmsis-driver-validation/blob - Source/DV_ETH.c
Updated component condition to accept both RTOS and RTOS2.
[cmsis-driver-validation] / Source / DV_ETH.c
1 /*-----------------------------------------------------------------------------
2  *      Name:         DV_Ethernet.c
3  *      Purpose:      Ethernet test cases
4  *----------------------------------------------------------------------------
5  *      Copyright(c) KEIL - An ARM Company
6  *----------------------------------------------------------------------------*/
7 #include "cmsis_dv.h" 
8 #include "DV_Config.h"
9 #include "DV_Framework.h"
10 #include "Driver_ETH_MAC.h"
11 #include "Driver_ETH_PHY.h"
12 #include <stdio.h>
13 #include <stdlib.h> 
14 #include <string.h> 
15
16 // Ethernet PTP time definitions 
17 #define PTP_S_NS         1000000000U 
18 #define PTP_TIME_REF     ETH_PTP_TIME_REF
19 #define PTP_TIME_REF_NS  ETH_PTP_TIME_REF*1000000U 
20
21 // Ethernet buffer pointers
22 static uint8_t *buffer_out; 
23 static uint8_t *buffer_in; 
24
25 // Register Driver_ETH_MAC# Driver_ETH_PHY#
26 extern ARM_DRIVER_ETH_MAC CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
27 extern ARM_DRIVER_ETH_PHY CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
28 static ARM_DRIVER_ETH_MAC* eth_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
29 static ARM_DRIVER_ETH_PHY* eth_phy = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
30 static ARM_ETH_MAC_CAPABILITIES capab;  
31
32 // Event flags
33 static uint8_t volatile Event; 
34
35 // Ethernet event
36 static void ETH_DrvEvent (uint32_t event) {
37   Event |= event;
38 }
39
40 // Ethernet transfer
41 int8_t ETH_RunTransfer (uint8_t *out, uint8_t *in, uint32_t cnt);
42 int8_t ETH_RunTransfer (uint8_t *out, uint8_t *in, uint32_t cnt) {
43   uint32_t tick;
44   
45   Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;     
46
47   eth_mac->SendFrame (out, cnt, 0);
48     
49   tick = GET_SYSTICK();
50   do {
51     if ((Event & ARM_ETH_MAC_EVENT_RX_FRAME) || (eth_mac->GetRxFrameSize() != 0)) {
52       eth_mac->ReadFrame (in, BUFFER[BUFFER_NUM-1]);     
53       return 0;
54     }
55   }
56   while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT));
57   
58   return -1;
59 }
60
61
62 /*-----------------------------------------------------------------------------
63  *      Test cases
64  *----------------------------------------------------------------------------*/
65
66 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
67 /**
68 \defgroup eth_funcs Ethernet Validation
69 \brief Ethernet test cases
70 \details
71 The Ethernet validation test performs the following checks:
72 - API interface compliance.
73 - Data communication with various transfer sizes and communication parameters.
74 - Loopback communication.
75
76 \anchor eth_loopback
77 Loopback Communication Setup
78 ----------------------------
79
80 To perform loopback communication tests, it is required to connect the RX and TX lines of the Ethernet cable together:
81
82 - TX+ (Pin 1) with RX+ (Pin 3) and
83 - TX- (Pin 2) with RX- (Pin 6)
84
85 \image html ethernet_loopback.png
86
87 Various \b Ethernet \b loopback \b plugs are available from different vendors that fulfill this purpose.
88
89 @{
90 */
91
92 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
93 /**
94 \brief Test case: ETH_MAC_GetCapabilities
95 \details
96 The test case \b ETH_MAC_GetCapabilities verifies the Ethernet MAC function \b GetCapabilities.
97 */
98 void ETH_MAC_GetCapabilities (void) {                    
99   /* Get ETH_MAC capabilities */
100   capab = eth_mac->GetCapabilities();
101   ASSERT_TRUE(&capab != NULL); 
102 }
103
104 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
105 /**
106 \brief Test case: ETH_MAC_Initialization
107 \details
108 The test case \b ETH_MAC_Initialization verifies the Ethernet MAC functions in the following order:
109   - \b Initialize  without callback
110   - \b Uninitialize
111   - \b Initialize with callback if supported
112   - \b Uninitialize
113 */
114 void ETH_MAC_Initialization (void) { 
115
116   /* Initialize without callback */
117   ASSERT_TRUE(eth_mac->Initialize(NULL) == ARM_DRIVER_OK); 
118     
119   /* Uninitialize */
120   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
121   
122   /* Initialize with callback if supported */
123   ASSERT_TRUE(eth_mac->Initialize((capab.event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
124   
125   /* Uninitialize */
126   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
127 }
128
129 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
130 /**
131 \brief Test case: ETH_MAC_CheckInvalidInit
132 \details
133 The test case \b ETH_MAC_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
134   - \b Uninitialize
135   - \b PowerControl with Power off
136   - \b PowerControl with Power on
137   - \b Control 
138   - \b PowerControl with Power off
139   - \b Uninitialize
140 */
141 void ETH_MAC_CheckInvalidInit (void) { 
142
143   /* Uninitialize */
144   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
145
146   /* Power off */
147   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
148   
149   /* Try to power on */
150   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK); 
151   
152   /* Try to set configuration */
153   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M  | ARM_ETH_MAC_DUPLEX_FULL | 
154     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL )!= ARM_DRIVER_OK);
155
156   /* Power off */
157   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
158   
159   /* Uninitialize */
160   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
161 }
162
163 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
164 /**
165 \brief Test case: ETH_MAC_PowerControl
166 \details
167 The test case \b ETH_MAC_PowerControl verifies the Ethernet MAC \b PowerControl function with the sequence:
168   - Initialize 
169   - Power on
170   - Set bus speed \token{10M}
171   - Set bus speed \token{100M}
172   - Set bus speed \token{1G} 
173   - Power off
174   - Uninitialize
175 */
176 void ETH_MAC_PowerControl (void) { 
177   int32_t val;
178   
179   /* Initialize with callback if supported */
180   ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
181   
182   /* Power on */
183   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);  
184   
185   /* Power low */
186   val = eth_mac->PowerControl (ARM_POWER_LOW);
187   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { SET_RESULT(WARNING, "Low power is not supported"); }
188   else { ASSERT_TRUE(val == ARM_DRIVER_OK); }
189    
190   /* Power off */
191   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
192   
193   /* Uninitialize */
194   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
195 }
196
197 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
198 /**
199 \brief Test case: ETH_MAC_SetBusSpeed
200 \details
201 The test case \b ETH_MAC_SetBusSpeed verifies the Ethernet MAC \b Control function with the sequence:
202   - Initialize 
203   - Power on
204   - Set bus speed \token{10M}
205   - Set bus speed \token{100M}
206   - Set bus speed \token{1G}
207   - Power off
208   - Uninitialize
209 */
210 void ETH_MAC_SetBusSpeed (void) { 
211   int32_t val;  
212   
213   /* Initialize with callback if supported and power on*/
214   ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
215   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);  
216   
217   /* Set bus speed 10M */
218   val = eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_10M);
219   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { SET_RESULT(WARNING, "Link speed 10M is not supported"); }
220   else { ASSERT_TRUE(val == ARM_DRIVER_OK); } 
221   
222   /* Set bus speed 100M */
223   val = eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M);
224   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { SET_RESULT(WARNING, "Link speed 100M is not supported"); }
225   else { ASSERT_TRUE(val == ARM_DRIVER_OK); } 
226   
227   /* Set bus speed 1G */
228   val = eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_1G);
229   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { SET_RESULT(WARNING, "Link speed 1G is not supported"); }
230   else { ASSERT_TRUE(val == ARM_DRIVER_OK); } 
231   
232   /* Power off and uninitialize */
233   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
234   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
235 }
236
237 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
238 /**
239 \brief Test case: ETH_MAC_Config_Mode
240 \details
241 The test case \b ETH_MAC_Config_Mode verifies the Ethernet MAC \b Control function with the sequence:
242   - Initialize 
243   - Power on
244   - Set full duplex
245   - Set half duplex 
246   - Power off
247   - Uninitialize
248 */
249 void ETH_MAC_Config_Mode (void) { 
250   
251   /* Initialize with callback if supported and power on*/
252   ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
253   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
254   
255   /* Set full duplex */
256   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_FULL)== ARM_DRIVER_OK);
257   
258   /* Set half duplex */
259   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_HALF)== ARM_DRIVER_OK);
260   
261   /* Power off and uninitialize */
262   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
263   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
264 }
265
266 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
267 /**
268 \brief Test case: ETH_MAC_Config_CommonParams
269 \details
270 The test case \b ETH_MAC_Config_CommonParams verifies the Ethernet MAC \b Control function with the sequence:
271   - Initialize 
272   - Power on
273   - Configure Ethernet MAC bus
274   - Configure receiver
275   - Configure transmitter
276   - Power off
277   - Uninitialize
278 */
279 void ETH_MAC_Config_CommonParams (void) { 
280   
281   /* Initialize with callback if supported and power on*/
282   ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
283   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
284   
285   /* Configure ETH_MAC bus*/
286   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M  | ARM_ETH_MAC_DUPLEX_FULL | 
287     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
288  
289   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
290
291   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
292   
293   /* Power off and uninitialize */
294   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
295   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
296 }
297
298 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
299 /**
300 \brief Test case: ETH_PHY_Initialization
301 \details
302 The test case \b ETH_PHY_Initialization verifies the Ethernet PHY functions in the following order:
303   - \b Initialize with read and write functions
304 */
305 void ETH_PHY_Initialization (void) { 
306   
307   /* MAC Initialize and power on */
308   ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
309   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
310
311   /* Initialize */
312   ASSERT_TRUE(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
313   
314   /* Uninitialize */
315   ASSERT_TRUE(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
316   
317   /* MAC Power off and uninitialize */
318   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
319   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
320 }
321
322 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
323 /**
324 \brief Test case: ETH_PHY_CheckInvalidInit
325 \details
326 The test case \b ETH_PHY_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
327   - \b Uninitialize
328   - \b PowerControl with Power off
329   - \b PowerControl with Power on
330   - \b SetInterface to configure the Ehternet PHY bus
331   - \b SetMode to configure the Ehternet PHY bus
332   - \b PowerControl with Power off
333   - \b Uninitialize
334 */
335 void ETH_PHY_CheckInvalidInit (void) { 
336     
337   /* Uninitialize */
338   ASSERT_TRUE(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
339   
340   /* Power off */
341   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
342   
343   /* Try to power on*/
344   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK); 
345   
346   /* Try to configure ETH_PHY bus*/
347   ASSERT_TRUE(eth_phy->SetInterface (capab.media_interface) != ARM_DRIVER_OK);  
348   ASSERT_TRUE(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) != ARM_DRIVER_OK);
349     
350   /* Try to initialize without read and write functions */
351   ASSERT_TRUE(eth_phy->Initialize(NULL, NULL) != ARM_DRIVER_OK); 
352   
353   /* Power off */
354   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
355   
356   /* Uninitialize */
357   ASSERT_TRUE(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
358 }
359
360 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
361 /**
362 \brief Test case: ETH_PHY_PowerControl
363 \details
364 The test case \b ETH_PHY_PowerControl verifies the Ethernet PHY \b PowerControl function with the sequence:
365   - Initialize
366   - Power on
367   - Power low
368   - Power off
369   - Uninitialize
370 */
371 void ETH_PHY_PowerControl (void) { 
372   int32_t val;
373   
374   /* MAC Initialize and power on */
375   ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
376   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
377   
378   /* Initialize */
379   ASSERT_TRUE(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
380   
381   /* Power on */
382   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);  
383   
384   /* Power low */
385   val = eth_phy->PowerControl (ARM_POWER_LOW);
386   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { SET_RESULT(WARNING, "Low power is not supported"); }
387   else { ASSERT_TRUE(val == ARM_DRIVER_OK); }
388    
389   /* Power off */
390   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
391   
392   /* Uninitialize */
393   ASSERT_TRUE(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
394   
395   /* MAC Power off and uninitialize */
396   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
397   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
398 }
399
400 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
401 /**
402 \brief  Test case: ETH_PHY_Config
403 \details
404 The test case \b ETH_PHY_Config verifies the PHY functions 
405   - Initialize
406   - Power on
407   - SetInterface 
408   - SetMode 
409   - Power off
410   - Uninitialize
411 */
412 void ETH_PHY_Config (void) { 
413   
414   /* MAC Initialize and power on*/
415   ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
416   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
417   
418   /* Initialize and power on*/
419   ASSERT_TRUE(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
420   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
421   
422   /* Configure ETH_PHY bus*/
423   ASSERT_TRUE(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK);
424   
425   ASSERT_TRUE(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
426   
427   /* Power off and uninitialize */
428   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
429   ASSERT_TRUE(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
430   
431   /* MAC Power off and uninitialize */
432   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
433   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
434 }
435
436 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
437 /**
438 \brief  Test case: ETH_Loopback_Transfer
439 \details
440 The test case \b ETH_Loopback_Transfer verifies data transfer via Ehernet with the following sequence:
441  - Buffer allocation
442  - Initialize
443  - Power on
444  - Ethernet connection
445  - Set output buffer pattern
446  - Transfer data chunks
447  - Set output buffer with random data
448  - Transfer data chunks
449  - Power off
450  - Uninitialize
451 */
452 void ETH_Loopback_Transfer (void) { 
453   uint16_t cnt, i; 
454   uint8_t pattern[] = BUFFER_PATTERN;
455   uint32_t tick;
456   char str[64];
457   
458   /* Allocate buffer */
459   buffer_out = (uint8_t*) malloc(BUFFER[BUFFER_NUM-1]*sizeof(uint8_t));
460   ASSERT_TRUE(buffer_out != NULL);
461   buffer_in = (uint8_t*) malloc(BUFFER[BUFFER_NUM-1]*sizeof(uint8_t));
462   ASSERT_TRUE(buffer_in != NULL);
463   
464   /* Initialize, power on and configure MAC and PHY */
465   ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
466   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
467   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M  | ARM_ETH_MAC_DUPLEX_FULL | 
468     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK); 
469   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
470   ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
471   ASSERT_TRUE(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
472   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
473   ASSERT_TRUE(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK); 
474   ASSERT_TRUE(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
475   
476   /* Check Ethernet link*/
477   tick = GET_SYSTICK();
478   while (eth_phy->GetLinkState() != ARM_ETH_LINK_UP) {
479     if ((GET_SYSTICK() - tick) >= SYSTICK_MICROSEC(ETH_LINK_TIMEOUT)) {
480       SET_RESULT(FAILED, "Link is broken, connect Ethernet cable");
481       break;
482     }
483   }   
484   
485   /* Set output buffer pattern*/
486   for (cnt = 0; cnt<BUFFER[BUFFER_NUM-1];) {  
487     for (i = 0; i<ARRAY_SIZE(pattern); i++) {
488       buffer_out[cnt++] = pattern[i];
489     }
490   } 
491  
492   /* Transfer data chunks */
493   for (cnt = 0; cnt<BUFFER_NUM; cnt++) {      
494     /* Clear input buffer*/
495     memset(buffer_in,0,BUFFER[cnt]);    
496     if (ETH_RunTransfer(buffer_out, buffer_in, BUFFER[cnt]) != ARM_DRIVER_OK) {
497       sprintf(str,"Fail to transfer block of %d bytes",BUFFER[cnt]);
498       SET_RESULT(FAILED, str);
499     } else SET_RESULT(PASSED, NULL);     
500     if (memcmp(buffer_in, buffer_out, BUFFER[cnt])!=0) {
501       sprintf(str,"Fail to check block of %d bytes",BUFFER[cnt]);
502       SET_RESULT(FAILED, str);
503     } else SET_RESULT(PASSED, NULL);     
504   } 
505   
506   /* Set output buffer with random data*/
507   srand(GET_SYSTICK());
508   for (cnt = 0; cnt<BUFFER[BUFFER_NUM-1]; cnt++) {  
509     buffer_out[cnt] = (uint8_t)rand();
510   }   
511   
512   /* Transfer data chunks */
513   for (cnt = 0; cnt<BUFFER_NUM; cnt++) {      
514     /* Clear input buffer*/
515     memset(buffer_in,0,BUFFER[cnt]);    
516     if (ETH_RunTransfer(buffer_out, buffer_in, BUFFER[cnt]) != ARM_DRIVER_OK) {
517       sprintf(str,"Fail to transfer block of %d bytes",BUFFER[cnt]);
518       SET_RESULT(FAILED, str);
519     } else SET_RESULT(PASSED, NULL);     
520     if (memcmp(buffer_in, buffer_out, BUFFER[cnt])!=0) {
521       sprintf(str,"Fail to check block of %d bytes",BUFFER[cnt]);
522       SET_RESULT(FAILED, str);
523     } else SET_RESULT(PASSED, NULL);     
524   } 
525   
526   /* Power off and uninitialize */
527   ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
528   ASSERT_TRUE(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
529   ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);  
530   ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
531   
532   /* Free buffer */
533   free(buffer_out);   
534   free(buffer_in); 
535 }
536
537 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
538 /**
539 \brief Test case: ETH_MAC_PTP_ControlTimer
540 \details
541 The test case \b ETH_MAC_PTP_ControlTimer verifies the PTP ControlTimer function with the sequence:
542   - Initialize 
543   - Power on
544   - Set Time
545   - Adjust Clock
546   - Increment Time
547   - Decrement Time
548   - Set Alarm
549   - Power off
550   - Uninitialize
551 */
552 void ETH_MAC_PTP_ControlTimer (void) { 
553   ARM_ETH_MAC_TIME time1, time2;
554   int64_t t1ns, t2ns, t, overhead;
555   double rate;
556   char str[64];
557     
558   /* Get capabilities */
559   if (!eth_mac->GetCapabilities().precision_timer) { 
560     SET_RESULT(WARNING, "Precision Time Protocol is not supported");    
561   } else {    
562     /* Initialize, power on and configure MAC */
563     ASSERT_TRUE(eth_mac->Initialize(ETH_DrvEvent) == ARM_DRIVER_OK); 
564     ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);  
565     
566     /* Set Time -------------------------------------------------------------------------------- */
567     time1.sec = 0U;
568     time1.ns = 0U;
569     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);   
570         
571     /* Check System Time */
572     osDelay(1U);
573     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
574     osDelay(PTP_TIME_REF);
575     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK); 
576     
577     /* Get timestamps in nanoseconds */
578     t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
579     t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
580     t = t2ns - t1ns - PTP_TIME_REF_NS;
581
582     /* Check timestamps difference */       
583     if (llabs(t)>ETH_PTP_TOLERANCE) {
584       sprintf(str,"PTP measured time is %lldns from expected", t);
585       SET_RESULT(WARNING, str);
586     } else SET_RESULT(PASSED, NULL);     
587     
588     /* Adjust clock - Set correction factor ---------------------------------------------------- */
589     /* Calculate rate and convert it to q31 format */
590     rate = (double)PTP_TIME_REF_NS/(t2ns-t1ns);    
591     time1.ns = (uint32_t)(0x80000000U*rate);
592     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_ADJUST_CLOCK, &time1) == ARM_DRIVER_OK); 
593     
594     /* Check System Time after adjusting clock */
595     osDelay(1U);
596     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
597     osDelay(PTP_TIME_REF);
598     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK); 
599     
600     /* Get timestamps in nanoseconds */
601     t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
602     t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns; 
603     t = t2ns - t1ns - PTP_TIME_REF_NS;
604        
605     /* Check timestamps difference */       
606     if (llabs(t)>ETH_PTP_TOLERANCE) {
607       sprintf(str,"PTP measured time with adj clk is %lldns from expected", t);
608       SET_RESULT(WARNING, str);
609     } else SET_RESULT(PASSED, NULL);  
610     
611     /* Measure time overhead for increment/decrement calls ------------------------------------- */
612     time2.sec = 0;
613     time2.ns = 0;
614     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
615     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_INC_TIME, &time2) == ARM_DRIVER_OK); 
616     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK); 
617     t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
618     t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
619     overhead = t2ns - t1ns;
620     
621     /* Increment time -------------------------------------------------------------------------- */
622     time2.sec = PTP_TIME_REF/1000U;
623     time2.ns = (PTP_TIME_REF-time2.sec*1000U)*1000000U;
624     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
625     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_INC_TIME, &time2) == ARM_DRIVER_OK); 
626     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);    
627
628     /* Get timestamps in nanoseconds */
629     t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
630     t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
631     t = t2ns - t1ns - PTP_TIME_REF_NS - overhead;
632     
633     /* Check timestamps difference */    
634     if (llabs(t)>ETH_PTP_TOLERANCE) {
635       sprintf(str,"PTP incremented time is %lldns from expected", t);
636       SET_RESULT(WARNING, str);
637     } else SET_RESULT(PASSED, NULL);   
638     
639     /* Decrement time -------------------------------------------------------------------------- */
640     time2.sec = PTP_TIME_REF/1000U;
641     time2.ns = (PTP_TIME_REF-time2.sec*1000U)*1000000U;
642     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
643     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_DEC_TIME, &time2) == ARM_DRIVER_OK); 
644     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);    
645
646     /* Get timestamps in nanoseconds */
647     t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
648     t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
649     t = t2ns - t1ns + PTP_TIME_REF_NS - overhead;
650         
651     /* Check timestamps difference */    
652     if (llabs(t)>ETH_PTP_TOLERANCE) {
653       sprintf(str,"PTP decremented time is %lldns from expected", t);
654       SET_RESULT(WARNING, str);
655     } else SET_RESULT(PASSED, NULL);     
656     
657     /* Set Alarm (1s) -------------------------------------------------------------------------- */
658     Event &= ~ARM_ETH_MAC_EVENT_TIMER_ALARM;
659     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK); 
660     time1.sec += 1U;
661     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_ALARM, &time1) == ARM_DRIVER_OK); 
662     
663     /* Check alarm event after 999ms */
664     osDelay(999U);
665     if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) != 0)  {
666       SET_RESULT(FAILED, "PTP Alarm event triggered too early");
667     } else SET_RESULT(PASSED, NULL); 
668     
669     /* Check alarm event after 1001ms */
670     osDelay(2U);
671     if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) == 0)  {
672       SET_RESULT(FAILED, "PTP Alarm event timeout");
673     } else SET_RESULT(PASSED, NULL);   
674
675     /* Power off and uninitialize */
676     ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);  
677     ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
678   }
679 }
680
681 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
682 /**
683 \brief Test case: ETH_Loopback_PTP
684 \details
685 The test case \b ETH_Loopback_PTP verifies the Precision Time Protocol functions ControlTimer, GetRxFrameTime and 
686 GetTxFrameTime with the sequence:
687   - Initialize 
688   - Power on
689   - Set Control Timer
690   - Transfer a frame
691   - Get TX frame time
692   - Get RX frame time
693   - Power off
694   - Uninitialize
695 */
696 void ETH_Loopback_PTP (void) { 
697   ARM_ETH_MAC_TIME time1, time2;
698   uint32_t tick;
699    
700   // PTP over Ethernet IPv4 sample frame
701   const uint8_t PTP_frame[] = {   
702    0x01, 0x00, 0x5e, 0x00, 0x01, 0x81, 0x00, 0x30, 0x05, 0x1d, 0x1e, 0x27, 0x08, 0x00, 0x45, 0x00,
703    0x00, 0x98, 0x00, 0x5d, 0x40, 0x00, 0x01, 0x11, 0x29, 0x68, 0x0a, 0x0a, 0x64, 0x05, 0xe0, 0x00,
704    0x01, 0x81, 0x01, 0x3f, 0x01, 0x3f, 0x00, 0x84, 0xc0, 0x7b, 0x00, 0x01, 0x00, 0x01, 0x5f, 0x44,
705    0x46, 0x4c, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
706    0x00, 0x30, 0x05, 0x1d, 0x1e, 0x27, 0x00, 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
707    0x00, 0x00, 0x45, 0x5b, 0x0a, 0x38, 0x0e, 0xb9, 0x26, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
708    0x00, 0x30, 0x05, 0x1d, 0x1e, 0x27, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x04, 0x44, 0x46,
709    0x4c, 0x54, 0x00, 0x00, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
710    0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x46, 0x4c, 0x54, 0x00, 0x01,
711    0x00, 0x30, 0x05, 0x1d, 0x1e, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712    0x00, 0x00, 0x00, 0x00, 0x00, 0x00                               
713   };
714   const uint32_t PTP_frame_len = sizeof(PTP_frame);    
715     
716   /* Get capabilities */
717   if (!eth_mac->GetCapabilities().precision_timer) { 
718     SET_RESULT(WARNING, "Precision Time Protocol is not supported");
719   } else {    
720     /* Allocate buffer */
721     buffer_in = (uint8_t*) malloc(PTP_frame_len*sizeof(uint8_t));
722     ASSERT_TRUE(buffer_in != NULL);
723     
724     /* Initialize, power on and configure MAC and PHY */
725     ASSERT_TRUE(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
726     ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
727     ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M  | ARM_ETH_MAC_DUPLEX_FULL | 
728       ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK); 
729     ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
730     ASSERT_TRUE(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
731     ASSERT_TRUE(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
732     ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
733     ASSERT_TRUE(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK); 
734     ASSERT_TRUE(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK); 
735     
736     /* Set Time */
737     time1.sec = 0U;
738     time1.ns = 0U;
739     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK); 
740     
741     /* Check timestamps - verify if control timer is running */
742     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK); 
743     ASSERT_TRUE(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);   
744     ASSERT_TRUE((time2.sec==time1.sec)?(time2.ns>time1.ns):(time2.sec>time1.sec)); 
745     
746     /* Check Ethernet link */
747     tick = GET_SYSTICK();
748     while (eth_phy->GetLinkState() != ARM_ETH_LINK_UP) {
749       if ((GET_SYSTICK() - tick) >= SYSTICK_MICROSEC(ETH_LINK_TIMEOUT)) {
750         SET_RESULT(FAILED, "Link is broken, connect Ethernet cable");
751         break;
752       }
753     }           
754     
755     /* Transfer frame */ 
756     ASSERT_TRUE(eth_mac->SendFrame (PTP_frame, PTP_frame_len, ARM_ETH_MAC_TX_FRAME_TIMESTAMP) == ARM_DRIVER_OK);    
757     tick = GET_SYSTICK();
758     while (eth_mac->GetRxFrameSize() == 0) {
759       if ((GET_SYSTICK() - tick) >= SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT)) {
760         SET_RESULT(FAILED, "Transfer timeout");
761         break;
762       }
763     }
764     
765     /* Get TX Frame Time */
766     ASSERT_TRUE(eth_mac->GetTxFrameTime(&time1) == ARM_DRIVER_OK); 
767     
768     /* Get RX Frame Time */
769     ASSERT_TRUE(eth_mac->GetRxFrameTime(&time2) == ARM_DRIVER_OK); 
770     
771     /* Check timestamps */
772     ASSERT_TRUE((time2.sec==time1.sec)?(time2.ns>time1.ns):(time2.sec>time1.sec)); 
773     
774     /* Check frame */
775     eth_mac->ReadFrame(buffer_in, PTP_frame_len);      
776     ASSERT_TRUE(memcmp(buffer_in, PTP_frame, PTP_frame_len) == 0);
777   
778     /* Power off and uninitialize */
779     ASSERT_TRUE(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
780     ASSERT_TRUE(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
781     ASSERT_TRUE(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);  
782     ASSERT_TRUE(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
783     
784     /* Free buffer */
785     free(buffer_in); 
786   }
787 }
788
789
790 /**
791 @}
792 */ 
793 // end of group eth_funcs