1 /*-----------------------------------------------------------------------------
3 * Purpose: Ethernet test cases
4 *----------------------------------------------------------------------------
5 * Copyright(c) KEIL - An ARM Company
6 *----------------------------------------------------------------------------*/
9 #include "DV_Framework.h"
10 #include "Driver_ETH_MAC.h"
11 #include "Driver_ETH_PHY.h"
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
21 // Ethernet buffer pointers
22 static uint8_t *buffer_out;
23 static uint8_t *buffer_in;
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;
35 static uint8_t volatile Event;
38 static void ETH_DrvEvent (uint32_t event) {
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) {
47 Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;
49 eth_mac->SendFrame (out, cnt, 0);
53 if ((Event & ARM_ETH_MAC_EVENT_RX_FRAME) || (eth_mac->GetRxFrameSize() != 0)) {
54 eth_mac->ReadFrame (in, BUFFER[BUFFER_NUM-1]);
58 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT));
64 /*-----------------------------------------------------------------------------
66 *----------------------------------------------------------------------------*/
68 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
70 \defgroup eth_funcs Ethernet Validation
71 \brief Ethernet test cases
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.
79 Loopback Communication Setup
80 ----------------------------
82 To perform loopback communication tests, it is required to connect the RX and TX lines of the Ethernet cable together:
84 - TX+ (Pin 1) with RX+ (Pin 3) and
85 - TX- (Pin 2) with RX- (Pin 6)
87 \image html ethernet_loopback.png
89 Various \b Ethernet \b loopback \b plugs are available from different vendors that fulfill this purpose.
94 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
96 \brief Test case: ETH_MAC_GetCapabilities
98 The test case \b ETH_MAC_GetCapabilities verifies the Ethernet MAC function \b GetCapabilities.
100 void ETH_MAC_GetCapabilities (void) {
101 /* Get ETH_MAC capabilities */
102 capab = eth_mac->GetCapabilities();
103 TEST_ASSERT(&capab != NULL);
106 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
108 \brief Test case: ETH_MAC_Initialization
110 The test case \b ETH_MAC_Initialization verifies the Ethernet MAC functions in the following order:
111 - \b Initialize without callback
113 - \b Initialize with callback if supported
116 void ETH_MAC_Initialization (void) {
118 /* Initialize without callback */
119 TEST_ASSERT(eth_mac->Initialize(NULL) == ARM_DRIVER_OK);
122 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
124 /* Initialize with callback if supported */
125 TEST_ASSERT(eth_mac->Initialize((capab.event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK);
128 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
131 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
133 \brief Test case: ETH_MAC_CheckInvalidInit
135 The test case \b ETH_MAC_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
137 - \b PowerControl with Power off
138 - \b PowerControl with Power on
140 - \b PowerControl with Power off
143 void ETH_MAC_CheckInvalidInit (void) {
146 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
149 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
151 /* Try to power on */
152 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
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);
159 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
162 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
165 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
167 \brief Test case: ETH_MAC_PowerControl
169 The test case \b ETH_MAC_PowerControl verifies the Ethernet MAC \b PowerControl function with the sequence:
172 - Set bus speed \token{10M}
173 - Set bus speed \token{100M}
174 - Set bus speed \token{1G}
178 void ETH_MAC_PowerControl (void) {
181 /* Initialize with callback if supported */
182 TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK);
185 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
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); }
193 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
196 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
199 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
201 \brief Test case: ETH_MAC_SetBusSpeed
203 The test case \b ETH_MAC_SetBusSpeed verifies the Ethernet MAC \b Control function with the sequence:
206 - Set bus speed \token{10M}
207 - Set bus speed \token{100M}
208 - Set bus speed \token{1G}
212 void ETH_MAC_SetBusSpeed (void) {
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);
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); }
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); }
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); }
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);
239 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
241 \brief Test case: ETH_MAC_Config_Mode
243 The test case \b ETH_MAC_Config_Mode verifies the Ethernet MAC \b Control function with the sequence:
251 void ETH_MAC_Config_Mode (void) {
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);
257 /* Set full duplex */
258 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_FULL)== ARM_DRIVER_OK);
260 /* Set half duplex */
261 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_HALF)== ARM_DRIVER_OK);
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);
268 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
270 \brief Test case: ETH_MAC_Config_CommonParams
272 The test case \b ETH_MAC_Config_CommonParams verifies the Ethernet MAC \b Control function with the sequence:
275 - Configure Ethernet MAC bus
277 - Configure transmitter
281 void ETH_MAC_Config_CommonParams (void) {
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);
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);
291 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
293 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
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);
300 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
302 \brief Test case: ETH_PHY_Initialization
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
307 void ETH_PHY_Initialization (void) {
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);
314 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
317 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
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);
324 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
326 \brief Test case: ETH_PHY_CheckInvalidInit
328 The test case \b ETH_PHY_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
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
337 void ETH_PHY_CheckInvalidInit (void) {
340 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
343 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
346 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
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);
352 /* Try to initialize without read and write functions */
353 TEST_ASSERT(eth_phy->Initialize(NULL, NULL) != ARM_DRIVER_OK);
356 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
359 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
362 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
364 \brief Test case: ETH_PHY_PowerControl
366 The test case \b ETH_PHY_PowerControl verifies the Ethernet PHY \b PowerControl function with the sequence:
373 void ETH_PHY_PowerControl (void) {
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);
381 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
384 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
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); }
392 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
395 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
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);
402 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
404 \brief Test case: ETH_PHY_Config
406 The test case \b ETH_PHY_Config verifies the PHY functions
414 void ETH_PHY_Config (void) {
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);
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);
424 /* Configure ETH_PHY bus*/
425 TEST_ASSERT(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK);
427 TEST_ASSERT(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
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);
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);
438 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
440 \brief Test case: ETH_Loopback_Transfer
442 The test case \b ETH_Loopback_Transfer verifies data transfer via Ehernet with the following sequence:
446 - Ethernet connection
447 - Set output buffer pattern
448 - Transfer data chunks
449 - Set output buffer with random data
450 - Transfer data chunks
454 void ETH_Loopback_Transfer (void) {
456 uint8_t pattern[] = BUFFER_PATTERN;
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);
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);
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");
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];
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);
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);
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();
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);
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);
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);
538 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
540 \brief Test case: ETH_MAC_PTP_ControlTimer
542 The test case \b ETH_MAC_PTP_ControlTimer verifies the PTP ControlTimer function with the sequence:
553 void ETH_MAC_PTP_ControlTimer (void) {
554 ARM_ETH_MAC_TIME time1, time2;
555 int64_t t1ns, t2ns, t, overhead;
558 /* Get capabilities */
559 if (!eth_mac->GetCapabilities().precision_timer) {
560 TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
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);
566 /* Set Time -------------------------------------------------------------------------------- */
569 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
571 /* Check System Time */
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);
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;
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);
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);
594 /* Check System Time after adjusting clock */
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);
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;
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);
611 /* Measure time overhead for increment/decrement calls ------------------------------------- */
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;
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);
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;
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);
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);
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;
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);
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);
661 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_ALARM, &time1) == ARM_DRIVER_OK);
663 /* Check alarm event after 999ms */
665 if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) != 0) {
666 TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event triggered too early");
669 /* Check alarm event after 1001ms */
671 if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) == 0) {
672 TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event timeout");
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);
681 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
683 \brief Test case: ETH_Loopback_PTP
685 The test case \b ETH_Loopback_PTP verifies the Precision Time Protocol functions ControlTimer, GetRxFrameTime and
686 GetTxFrameTime with the sequence:
696 void ETH_Loopback_PTP (void) {
697 ARM_ETH_MAC_TIME time1, time2;
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
714 const uint32_t PTP_frame_len = sizeof(PTP_frame);
716 /* Get capabilities */
717 if (!eth_mac->GetCapabilities().precision_timer) {
718 TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
720 /* Allocate buffer */
721 buffer_in = (uint8_t*) malloc(PTP_frame_len*sizeof(uint8_t));
722 TEST_ASSERT(buffer_in != NULL);
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);
739 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
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));
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");
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");
765 /* Get TX Frame Time */
766 TEST_ASSERT(eth_mac->GetTxFrameTime(&time1) == ARM_DRIVER_OK);
768 /* Get RX Frame Time */
769 TEST_ASSERT(eth_mac->GetRxFrameTime(&time2) == ARM_DRIVER_OK);
771 /* Check timestamps */
772 TEST_ASSERT((time2.sec==time1.sec)?(time2.ns>time1.ns):(time2.sec>time1.sec));
775 eth_mac->ReadFrame(buffer_in, PTP_frame_len);
776 TEST_ASSERT(memcmp(buffer_in, PTP_frame, PTP_frame_len) == 0);
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);
793 // end of group eth_funcs