1 /*-----------------------------------------------------------------------------
3 * Purpose: Ethernet test cases
4 *----------------------------------------------------------------------------
5 * Copyright(c) KEIL - An ARM Company
6 *----------------------------------------------------------------------------*/
10 #include "DV_Framework.h"
11 #include "Driver_ETH_MAC.h"
12 #include "Driver_ETH_PHY.h"
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
22 // Ethernet buffer pointers
23 static uint8_t *buffer_out;
24 static uint8_t *buffer_in;
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;
36 static uint8_t volatile Event;
39 static void ETH_DrvEvent (uint32_t event) {
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) {
48 Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;
50 eth_mac->SendFrame (out, cnt, 0);
54 if ((Event & ARM_ETH_MAC_EVENT_RX_FRAME) || (eth_mac->GetRxFrameSize() != 0)) {
55 eth_mac->ReadFrame (in, BUFFER[BUFFER_NUM-1]);
59 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT));
65 /*-----------------------------------------------------------------------------
67 *----------------------------------------------------------------------------*/
69 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
71 \defgroup eth_funcs Ethernet Validation
72 \brief Ethernet test cases
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.
80 Loopback Communication Setup
81 ----------------------------
83 To perform loopback communication tests, it is required to connect the RX and TX lines of the Ethernet cable together:
85 - TX+ (Pin 1) with RX+ (Pin 3) and
86 - TX- (Pin 2) with RX- (Pin 6)
88 \image html ethernet_loopback.png
90 Various \b Ethernet \b loopback \b plugs are available from different vendors that fulfill this purpose.
95 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
97 \brief Test case: ETH_MAC_GetCapabilities
99 The test case \b ETH_MAC_GetCapabilities verifies the Ethernet MAC function \b GetCapabilities.
101 void ETH_MAC_GetCapabilities (void) {
102 /* Get ETH_MAC capabilities */
103 capab = eth_mac->GetCapabilities();
104 TEST_ASSERT(&capab != NULL);
107 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
109 \brief Test case: ETH_MAC_Initialization
111 The test case \b ETH_MAC_Initialization verifies the Ethernet MAC functions in the following order:
112 - \b Initialize without callback
114 - \b Initialize with callback if supported
117 void ETH_MAC_Initialization (void) {
119 /* Initialize without callback */
120 TEST_ASSERT(eth_mac->Initialize(NULL) == ARM_DRIVER_OK);
123 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
125 /* Initialize with callback if supported */
126 TEST_ASSERT(eth_mac->Initialize((capab.event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK);
129 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
132 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
134 \brief Test case: ETH_MAC_CheckInvalidInit
136 The test case \b ETH_MAC_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
138 - \b PowerControl with Power off
139 - \b PowerControl with Power on
141 - \b PowerControl with Power off
144 void ETH_MAC_CheckInvalidInit (void) {
147 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
150 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
152 /* Try to power on */
153 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
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);
160 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
163 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
166 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
168 \brief Test case: ETH_MAC_PowerControl
170 The test case \b ETH_MAC_PowerControl verifies the Ethernet MAC \b PowerControl function with the sequence:
173 - Set bus speed \token{10M}
174 - Set bus speed \token{100M}
175 - Set bus speed \token{1G}
179 void ETH_MAC_PowerControl (void) {
182 /* Initialize with callback if supported */
183 TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK);
186 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
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); }
194 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
197 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
200 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
202 \brief Test case: ETH_MAC_SetBusSpeed
204 The test case \b ETH_MAC_SetBusSpeed verifies the Ethernet MAC \b Control function with the sequence:
207 - Set bus speed \token{10M}
208 - Set bus speed \token{100M}
209 - Set bus speed \token{1G}
213 void ETH_MAC_SetBusSpeed (void) {
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);
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); }
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); }
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); }
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);
240 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
242 \brief Test case: ETH_MAC_Config_Mode
244 The test case \b ETH_MAC_Config_Mode verifies the Ethernet MAC \b Control function with the sequence:
252 void ETH_MAC_Config_Mode (void) {
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);
258 /* Set full duplex */
259 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_FULL)== ARM_DRIVER_OK);
261 /* Set half duplex */
262 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_HALF)== ARM_DRIVER_OK);
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);
269 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
271 \brief Test case: ETH_MAC_Config_CommonParams
273 The test case \b ETH_MAC_Config_CommonParams verifies the Ethernet MAC \b Control function with the sequence:
276 - Configure Ethernet MAC bus
278 - Configure transmitter
282 void ETH_MAC_Config_CommonParams (void) {
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);
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);
292 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
294 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
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);
301 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
303 \brief Test case: ETH_PHY_Initialization
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
308 void ETH_PHY_Initialization (void) {
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);
315 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
318 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
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);
325 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
327 \brief Test case: ETH_PHY_CheckInvalidInit
329 The test case \b ETH_PHY_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
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
338 void ETH_PHY_CheckInvalidInit (void) {
341 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
344 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
347 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
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);
353 /* Try to initialize without read and write functions */
354 TEST_ASSERT(eth_phy->Initialize(NULL, NULL) != ARM_DRIVER_OK);
357 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
360 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
363 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
365 \brief Test case: ETH_PHY_PowerControl
367 The test case \b ETH_PHY_PowerControl verifies the Ethernet PHY \b PowerControl function with the sequence:
374 void ETH_PHY_PowerControl (void) {
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);
382 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
385 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
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); }
393 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
396 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
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);
403 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
405 \brief Test case: ETH_PHY_Config
407 The test case \b ETH_PHY_Config verifies the PHY functions
415 void ETH_PHY_Config (void) {
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);
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);
425 /* Configure ETH_PHY bus*/
426 TEST_ASSERT(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK);
428 TEST_ASSERT(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
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);
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);
439 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
441 \brief Test case: ETH_Loopback_Transfer
443 The test case \b ETH_Loopback_Transfer verifies data transfer via Ehernet with the following sequence:
447 - Ethernet connection
448 - Set output buffer pattern
449 - Transfer data chunks
450 - Set output buffer with random data
451 - Transfer data chunks
455 void ETH_Loopback_Transfer (void) {
457 uint8_t pattern[] = BUFFER_PATTERN;
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);
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);
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");
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];
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);
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);
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();
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);
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);
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);
539 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
541 \brief Test case: ETH_MAC_PTP_ControlTimer
543 The test case \b ETH_MAC_PTP_ControlTimer verifies the PTP ControlTimer function with the sequence:
554 void ETH_MAC_PTP_ControlTimer (void) {
555 ARM_ETH_MAC_TIME time1, time2;
556 int64_t t1ns, t2ns, t, overhead;
559 /* Get capabilities */
560 if (!eth_mac->GetCapabilities().precision_timer) {
561 TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
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);
567 /* Set Time -------------------------------------------------------------------------------- */
570 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
572 /* Check System Time */
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);
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;
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);
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);
595 /* Check System Time after adjusting clock */
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);
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;
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);
612 /* Measure time overhead for increment/decrement calls ------------------------------------- */
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;
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);
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;
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);
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);
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;
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);
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);
662 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_ALARM, &time1) == ARM_DRIVER_OK);
664 /* Check alarm event after 999ms */
666 if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) != 0) {
667 TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event triggered too early");
670 /* Check alarm event after 1001ms */
672 if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) == 0) {
673 TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event timeout");
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);
682 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
684 \brief Test case: ETH_Loopback_PTP
686 The test case \b ETH_Loopback_PTP verifies the Precision Time Protocol functions ControlTimer, GetRxFrameTime and
687 GetTxFrameTime with the sequence:
697 void ETH_Loopback_PTP (void) {
698 ARM_ETH_MAC_TIME time1, time2;
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
715 const uint32_t PTP_frame_len = sizeof(PTP_frame);
717 /* Get capabilities */
718 if (!eth_mac->GetCapabilities().precision_timer) {
719 TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
721 /* Allocate buffer */
722 buffer_in = (uint8_t*) malloc(PTP_frame_len*sizeof(uint8_t));
723 TEST_ASSERT(buffer_in != NULL);
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);
740 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
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));
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");
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");
766 /* Get TX Frame Time */
767 TEST_ASSERT(eth_mac->GetTxFrameTime(&time1) == ARM_DRIVER_OK);
769 /* Get RX Frame Time */
770 TEST_ASSERT(eth_mac->GetRxFrameTime(&time2) == ARM_DRIVER_OK);
772 /* Check timestamps */
773 TEST_ASSERT((time2.sec==time1.sec)?(time2.ns>time1.ns):(time2.sec>time1.sec));
776 eth_mac->ReadFrame(buffer_in, PTP_frame_len);
777 TEST_ASSERT(memcmp(buffer_in, PTP_frame, PTP_frame_len) == 0);
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);
794 // end of group eth_funcs