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