]> begriffs open source - cmsis-driver-validation/blob - Source/DV_ETH.c
Changes:
[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 static char str[128];
33
34 // Event flags
35 static uint8_t volatile Event; 
36
37 // Ethernet event
38 static void ETH_DrvEvent (uint32_t event) {
39   Event |= event;
40 }
41
42 // Ethernet transfer
43 int8_t ETH_RunTransfer (uint8_t *out, uint8_t *in, uint32_t cnt);
44 int8_t ETH_RunTransfer (uint8_t *out, uint8_t *in, uint32_t cnt) {
45   uint32_t tick;
46   
47   Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;     
48
49   eth_mac->SendFrame (out, cnt, 0);
50     
51   tick = GET_SYSTICK();
52   do {
53     if ((Event & ARM_ETH_MAC_EVENT_RX_FRAME) || (eth_mac->GetRxFrameSize() != 0)) {
54       eth_mac->ReadFrame (in, BUFFER[BUFFER_NUM-1]);     
55       return 0;
56     }
57   }
58   while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT));
59   
60   return -1;
61 }
62
63
64 /*-----------------------------------------------------------------------------
65  *      Test cases
66  *----------------------------------------------------------------------------*/
67
68 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
69 /**
70 \defgroup eth_funcs Ethernet Validation
71 \brief Ethernet test cases
72 \details
73 The Ethernet validation test performs the following checks:
74 - API interface compliance.
75 - Data communication with various transfer sizes and communication parameters.
76 - Loopback communication.
77
78 \anchor eth_loopback
79 Loopback Communication Setup
80 ----------------------------
81
82 To perform loopback communication tests, it is required to connect the RX and TX lines of the Ethernet cable together:
83
84 - TX+ (Pin 1) with RX+ (Pin 3) and
85 - TX- (Pin 2) with RX- (Pin 6)
86
87 \image html ethernet_loopback.png
88
89 Various \b Ethernet \b loopback \b plugs are available from different vendors that fulfill this purpose.
90
91 @{
92 */
93
94 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
95 /**
96 \brief Test case: ETH_MAC_GetCapabilities
97 \details
98 The test case \b ETH_MAC_GetCapabilities verifies the Ethernet MAC function \b GetCapabilities.
99 */
100 void ETH_MAC_GetCapabilities (void) {                    
101   /* Get ETH_MAC capabilities */
102   capab = eth_mac->GetCapabilities();
103   TEST_ASSERT(&capab != NULL); 
104 }
105
106 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
107 /**
108 \brief Test case: ETH_MAC_Initialization
109 \details
110 The test case \b ETH_MAC_Initialization verifies the Ethernet MAC functions in the following order:
111   - \b Initialize  without callback
112   - \b Uninitialize
113   - \b Initialize with callback if supported
114   - \b Uninitialize
115 */
116 void ETH_MAC_Initialization (void) { 
117
118   /* Initialize without callback */
119   TEST_ASSERT(eth_mac->Initialize(NULL) == ARM_DRIVER_OK); 
120     
121   /* Uninitialize */
122   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
123   
124   /* Initialize with callback if supported */
125   TEST_ASSERT(eth_mac->Initialize((capab.event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
126   
127   /* Uninitialize */
128   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
129 }
130
131 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
132 /**
133 \brief Test case: ETH_MAC_CheckInvalidInit
134 \details
135 The test case \b ETH_MAC_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
136   - \b Uninitialize
137   - \b PowerControl with Power off
138   - \b PowerControl with Power on
139   - \b Control 
140   - \b PowerControl with Power off
141   - \b Uninitialize
142 */
143 void ETH_MAC_CheckInvalidInit (void) { 
144
145   /* Uninitialize */
146   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
147
148   /* Power off */
149   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
150   
151   /* Try to power on */
152   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK); 
153   
154   /* Try to set configuration */
155   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M  | ARM_ETH_MAC_DUPLEX_FULL | 
156     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL )!= ARM_DRIVER_OK);
157
158   /* Power off */
159   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
160   
161   /* Uninitialize */
162   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
163 }
164
165 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
166 /**
167 \brief Test case: ETH_MAC_PowerControl
168 \details
169 The test case \b ETH_MAC_PowerControl verifies the Ethernet MAC \b PowerControl function with the sequence:
170   - Initialize 
171   - Power on
172   - Set bus speed \token{10M}
173   - Set bus speed \token{100M}
174   - Set bus speed \token{1G} 
175   - Power off
176   - Uninitialize
177 */
178 void ETH_MAC_PowerControl (void) { 
179   int32_t val;
180   
181   /* Initialize with callback if supported */
182   TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
183   
184   /* Power on */
185   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);  
186   
187   /* Power low */
188   val = eth_mac->PowerControl (ARM_POWER_LOW);
189   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
190   else { TEST_ASSERT(val == ARM_DRIVER_OK); }
191    
192   /* Power off */
193   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
194   
195   /* Uninitialize */
196   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
197 }
198
199 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
200 /**
201 \brief Test case: ETH_MAC_SetBusSpeed
202 \details
203 The test case \b ETH_MAC_SetBusSpeed verifies the Ethernet MAC \b Control function with the sequence:
204   - Initialize 
205   - Power on
206   - Set bus speed \token{10M}
207   - Set bus speed \token{100M}
208   - Set bus speed \token{1G}
209   - Power off
210   - Uninitialize
211 */
212 void ETH_MAC_SetBusSpeed (void) { 
213   int32_t val;  
214   
215   /* Initialize with callback if supported and power on*/
216   TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
217   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);  
218   
219   /* Set bus speed 10M */
220   val = eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_10M);
221   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 10M is not supported"); }
222   else { TEST_ASSERT(val == ARM_DRIVER_OK); } 
223   
224   /* Set bus speed 100M */
225   val = eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M);
226   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 100M is not supported"); }
227   else { TEST_ASSERT(val == ARM_DRIVER_OK); } 
228   
229   /* Set bus speed 1G */
230   val = eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_1G);
231   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 1G is not supported"); }
232   else { TEST_ASSERT(val == ARM_DRIVER_OK); } 
233   
234   /* Power off and uninitialize */
235   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
236   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
237 }
238
239 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
240 /**
241 \brief Test case: ETH_MAC_Config_Mode
242 \details
243 The test case \b ETH_MAC_Config_Mode verifies the Ethernet MAC \b Control function with the sequence:
244   - Initialize 
245   - Power on
246   - Set full duplex
247   - Set half duplex 
248   - Power off
249   - Uninitialize
250 */
251 void ETH_MAC_Config_Mode (void) { 
252   
253   /* Initialize with callback if supported and power on*/
254   TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
255   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
256   
257   /* Set full duplex */
258   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_FULL)== ARM_DRIVER_OK);
259   
260   /* Set half duplex */
261   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_HALF)== ARM_DRIVER_OK);
262   
263   /* Power off and uninitialize */
264   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
265   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
266 }
267
268 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
269 /**
270 \brief Test case: ETH_MAC_Config_CommonParams
271 \details
272 The test case \b ETH_MAC_Config_CommonParams verifies the Ethernet MAC \b Control function with the sequence:
273   - Initialize 
274   - Power on
275   - Configure Ethernet MAC bus
276   - Configure receiver
277   - Configure transmitter
278   - Power off
279   - Uninitialize
280 */
281 void ETH_MAC_Config_CommonParams (void) { 
282   
283   /* Initialize with callback if supported and power on*/
284   TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
285   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
286   
287   /* Configure ETH_MAC bus*/
288   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M  | ARM_ETH_MAC_DUPLEX_FULL | 
289     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
290  
291   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
292
293   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
294   
295   /* Power off and uninitialize */
296   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
297   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
298 }
299
300 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
301 /**
302 \brief Test case: ETH_PHY_Initialization
303 \details
304 The test case \b ETH_PHY_Initialization verifies the Ethernet PHY functions in the following order:
305   - \b Initialize with read and write functions
306 */
307 void ETH_PHY_Initialization (void) { 
308   
309   /* MAC Initialize and power on */
310   TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
311   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
312
313   /* Initialize */
314   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
315   
316   /* Uninitialize */
317   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
318   
319   /* MAC Power off and uninitialize */
320   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
321   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
322 }
323
324 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
325 /**
326 \brief Test case: ETH_PHY_CheckInvalidInit
327 \details
328 The test case \b ETH_PHY_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
329   - \b Uninitialize
330   - \b PowerControl with Power off
331   - \b PowerControl with Power on
332   - \b SetInterface to configure the Ehternet PHY bus
333   - \b SetMode to configure the Ehternet PHY bus
334   - \b PowerControl with Power off
335   - \b Uninitialize
336 */
337 void ETH_PHY_CheckInvalidInit (void) { 
338     
339   /* Uninitialize */
340   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
341   
342   /* Power off */
343   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
344   
345   /* Try to power on*/
346   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK); 
347   
348   /* Try to configure ETH_PHY bus*/
349   TEST_ASSERT(eth_phy->SetInterface (capab.media_interface) != ARM_DRIVER_OK);  
350   TEST_ASSERT(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) != ARM_DRIVER_OK);
351     
352   /* Try to initialize without read and write functions */
353   TEST_ASSERT(eth_phy->Initialize(NULL, NULL) != ARM_DRIVER_OK); 
354   
355   /* Power off */
356   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
357   
358   /* Uninitialize */
359   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
360 }
361
362 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
363 /**
364 \brief Test case: ETH_PHY_PowerControl
365 \details
366 The test case \b ETH_PHY_PowerControl verifies the Ethernet PHY \b PowerControl function with the sequence:
367   - Initialize
368   - Power on
369   - Power low
370   - Power off
371   - Uninitialize
372 */
373 void ETH_PHY_PowerControl (void) { 
374   int32_t val;
375   
376   /* MAC Initialize and power on */
377   TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
378   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
379   
380   /* Initialize */
381   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
382   
383   /* Power on */
384   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);  
385   
386   /* Power low */
387   val = eth_phy->PowerControl (ARM_POWER_LOW);
388   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
389   else { TEST_ASSERT(val == ARM_DRIVER_OK); }
390    
391   /* Power off */
392   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
393   
394   /* Uninitialize */
395   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
396   
397   /* MAC Power off and uninitialize */
398   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
399   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
400 }
401
402 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
403 /**
404 \brief  Test case: ETH_PHY_Config
405 \details
406 The test case \b ETH_PHY_Config verifies the PHY functions 
407   - Initialize
408   - Power on
409   - SetInterface 
410   - SetMode 
411   - Power off
412   - Uninitialize
413 */
414 void ETH_PHY_Config (void) { 
415   
416   /* MAC Initialize and power on*/
417   TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
418   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
419   
420   /* Initialize and power on*/
421   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
422   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
423   
424   /* Configure ETH_PHY bus*/
425   TEST_ASSERT(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK);
426   
427   TEST_ASSERT(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
428   
429   /* Power off and uninitialize */
430   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
431   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
432   
433   /* MAC Power off and uninitialize */
434   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
435   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
436 }
437
438 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
439 /**
440 \brief  Test case: ETH_Loopback_Transfer
441 \details
442 The test case \b ETH_Loopback_Transfer verifies data transfer via Ehernet with the following sequence:
443  - Buffer allocation
444  - Initialize
445  - Power on
446  - Ethernet connection
447  - Set output buffer pattern
448  - Transfer data chunks
449  - Set output buffer with random data
450  - Transfer data chunks
451  - Power off
452  - Uninitialize
453 */
454 void ETH_Loopback_Transfer (void) { 
455   uint16_t cnt, i; 
456   uint8_t pattern[] = BUFFER_PATTERN;
457   uint32_t tick;
458   
459   /* Allocate buffer */
460   buffer_out = (uint8_t*) malloc(BUFFER[BUFFER_NUM-1]*sizeof(uint8_t));
461   TEST_ASSERT(buffer_out != NULL);
462   buffer_in = (uint8_t*) malloc(BUFFER[BUFFER_NUM-1]*sizeof(uint8_t));
463   TEST_ASSERT(buffer_in != NULL);
464   
465   /* Initialize, power on and configure MAC and PHY */
466   TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
467   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
468   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_SPEED_100M  | ARM_ETH_MAC_DUPLEX_FULL | 
469     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK); 
470   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
471   TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
472   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
473   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
474   TEST_ASSERT(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK); 
475   TEST_ASSERT(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
476   
477   /* Check Ethernet link*/
478   tick = GET_SYSTICK();
479   while (eth_phy->GetLinkState() != ARM_ETH_LINK_UP) {
480     if ((GET_SYSTICK() - tick) >= SYSTICK_MICROSEC(ETH_LINK_TIMEOUT)) {
481       TEST_FAIL_MESSAGE("[FAILED] Link is broken, connect Ethernet cable");
482       break;
483     }
484   }   
485   
486   /* Set output buffer pattern*/
487   for (cnt = 0; cnt<BUFFER[BUFFER_NUM-1];) {  
488     for (i = 0; i<ARRAY_SIZE(pattern); i++) {
489       buffer_out[cnt++] = pattern[i];
490     }
491   } 
492  
493   /* Transfer data chunks */
494   for (cnt = 0; cnt<BUFFER_NUM; cnt++) {      
495     /* Clear input buffer*/
496     memset(buffer_in,0,BUFFER[cnt]);    
497     if (ETH_RunTransfer(buffer_out, buffer_in, BUFFER[cnt]) != ARM_DRIVER_OK) {
498       snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",BUFFER[cnt]);
499       TEST_FAIL_MESSAGE(str);
500     } else TEST_PASS();     
501     if (memcmp(buffer_in, buffer_out, BUFFER[cnt])!=0) {
502       snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",BUFFER[cnt]);
503       TEST_FAIL_MESSAGE(str);
504     } else TEST_PASS();     
505   } 
506   
507   /* Set output buffer with random data*/
508   srand(GET_SYSTICK());
509   for (cnt = 0; cnt<BUFFER[BUFFER_NUM-1]; cnt++) {  
510     buffer_out[cnt] = (uint8_t)rand();
511   }   
512   
513   /* Transfer data chunks */
514   for (cnt = 0; cnt<BUFFER_NUM; cnt++) {      
515     /* Clear input buffer*/
516     memset(buffer_in,0,BUFFER[cnt]);    
517     if (ETH_RunTransfer(buffer_out, buffer_in, BUFFER[cnt]) != ARM_DRIVER_OK) {
518       snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",BUFFER[cnt]);
519       TEST_FAIL_MESSAGE(str);
520     } else TEST_PASS();     
521     if (memcmp(buffer_in, buffer_out, BUFFER[cnt])!=0) {
522       snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",BUFFER[cnt]);
523       TEST_FAIL_MESSAGE(str);
524     } else TEST_PASS();     
525   } 
526   
527   /* Power off and uninitialize */
528   TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
529   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
530   TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);  
531   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK); 
532   
533   /* Free buffer */
534   free(buffer_out);   
535   free(buffer_in); 
536 }
537
538 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
539 /**
540 \brief Test case: ETH_MAC_PTP_ControlTimer
541 \details
542 The test case \b ETH_MAC_PTP_ControlTimer verifies the PTP ControlTimer function with the sequence:
543   - Initialize 
544   - Power on
545   - Set Time
546   - Adjust Clock
547   - Increment Time
548   - Decrement Time
549   - Set Alarm
550   - Power off
551   - Uninitialize
552 */
553 void ETH_MAC_PTP_ControlTimer (void) { 
554   ARM_ETH_MAC_TIME time1, time2;
555   int64_t t1ns, t2ns, t, overhead;
556   double rate;
557     
558   /* Get capabilities */
559   if (!eth_mac->GetCapabilities().precision_timer) { 
560     TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");    
561   } else {    
562     /* Initialize, power on and configure MAC */
563     TEST_ASSERT(eth_mac->Initialize(ETH_DrvEvent) == ARM_DRIVER_OK); 
564     TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);  
565     
566     /* Set Time -------------------------------------------------------------------------------- */
567     time1.sec = 0U;
568     time1.ns = 0U;
569     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);   
570         
571     /* Check System Time */
572     osDelay(1U);
573     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
574     osDelay(PTP_TIME_REF);
575     TEST_ASSERT(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       snprintf(str,sizeof(str),"[WARNING] PTP measured time is %lldns from expected", t);
585       TEST_MESSAGE(str);
586     } else TEST_PASS();     
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     TEST_ASSERT(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     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
597     osDelay(PTP_TIME_REF);
598     TEST_ASSERT(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       snprintf(str,sizeof(str),"[WARNING] PTP measured time with adj clk is %lldns from expected", t);
608       TEST_MESSAGE(str);
609     } else TEST_PASS();  
610     
611     /* Measure time overhead for increment/decrement calls ------------------------------------- */
612     time2.sec = 0;
613     time2.ns = 0;
614     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
615     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_INC_TIME, &time2) == ARM_DRIVER_OK); 
616     TEST_ASSERT(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     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
625     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_INC_TIME, &time2) == ARM_DRIVER_OK); 
626     TEST_ASSERT(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       snprintf(str,sizeof(str),"[WARNING] PTP incremented time is %lldns from expected", t);
636       TEST_MESSAGE(str);
637     } else TEST_PASS();   
638     
639     /* Decrement time -------------------------------------------------------------------------- */
640     time2.sec = PTP_TIME_REF/1000U;
641     time2.ns = (PTP_TIME_REF-time2.sec*1000U)*1000000U;
642     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);  
643     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_DEC_TIME, &time2) == ARM_DRIVER_OK); 
644     TEST_ASSERT(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       snprintf(str,sizeof(str),"[WARNING] PTP decremented time is %lldns from expected", t);
654       TEST_MESSAGE(str);
655     } else TEST_PASS();     
656     
657     /* Set Alarm (1s) -------------------------------------------------------------------------- */
658     Event &= ~ARM_ETH_MAC_EVENT_TIMER_ALARM;
659     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK); 
660     time1.sec += 1U;
661     TEST_ASSERT(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       TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event triggered too early");
667     } else TEST_PASS(); 
668     
669     /* Check alarm event after 1001ms */
670     osDelay(2U);
671     if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) == 0)  {
672       TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event timeout");
673     } else TEST_PASS();   
674
675     /* Power off and uninitialize */
676     TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);  
677     TEST_ASSERT(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     TEST_MESSAGE("[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     TEST_ASSERT(buffer_in != NULL);
723     
724     /* Initialize, power on and configure MAC and PHY */
725     TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK); 
726     TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
727     TEST_ASSERT(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     TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
730     TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
731     TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK); 
732     TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK); 
733     TEST_ASSERT(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK); 
734     TEST_ASSERT(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK); 
735     
736     /* Set Time */
737     time1.sec = 0U;
738     time1.ns = 0U;
739     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK); 
740     
741     /* Check timestamps - verify if control timer is running */
742     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK); 
743     TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);   
744     TEST_ASSERT((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         TEST_FAIL_MESSAGE("[FAILED] Link is broken, connect Ethernet cable");
751         break;
752       }
753     }           
754     
755     /* Transfer frame */ 
756     TEST_ASSERT(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         TEST_FAIL_MESSAGE("[FAILED] Transfer timeout");
761         break;
762       }
763     }
764     
765     /* Get TX Frame Time */
766     TEST_ASSERT(eth_mac->GetTxFrameTime(&time1) == ARM_DRIVER_OK); 
767     
768     /* Get RX Frame Time */
769     TEST_ASSERT(eth_mac->GetRxFrameTime(&time2) == ARM_DRIVER_OK); 
770     
771     /* Check timestamps */
772     TEST_ASSERT((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     TEST_ASSERT(memcmp(buffer_in, PTP_frame, PTP_frame_len) == 0);
777   
778     /* Power off and uninitialize */
779     TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
780     TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK); 
781     TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);  
782     TEST_ASSERT(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