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