2 * Copyright (c) 2015-2020 Arm Limited. All rights reserved.
4 * SPDX-License-Identifier: Apache-2.0
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
10 * www.apache.org/licenses/LICENSE-2.0
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.
18 * -----------------------------------------------------------------------------
20 * Project: CMSIS-Driver Validation
21 * Title: Ethernet (ETH) Driver Validation tests
23 * -----------------------------------------------------------------------------
28 #include "DV_ETH_Config.h"
29 #include "DV_Framework.h"
30 #include "Driver_ETH_MAC.h"
31 #include "Driver_ETH_PHY.h"
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
41 // Ethernet buffer pointers
42 static uint8_t *buffer_out;
43 static uint8_t *buffer_in;
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;
55 static uint8_t volatile Event;
58 static void ETH_DrvEvent (uint32_t event) {
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) {
67 Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;
69 eth_mac->SendFrame (out, cnt, 0);
73 if ((Event & ARM_ETH_MAC_EVENT_RX_FRAME) || (eth_mac->GetRxFrameSize() != 0)) {
74 eth_mac->ReadFrame (in, BUFFER[BUFFER_NUM-1]);
78 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT));
84 /*-----------------------------------------------------------------------------
86 *----------------------------------------------------------------------------*/
88 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
90 \defgroup dv_eth Ethernet Validation
91 \brief Ethernet driver validation
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.
99 Loopback Communication Setup
100 ----------------------------
102 To perform loopback communication tests, it is required to connect the RX and TX lines of the Ethernet cable together:
104 - TX+ (Pin 1) with RX+ (Pin 3) and
105 - TX- (Pin 2) with RX- (Pin 6)
107 \image html ethernet_loopback.png
109 Various \b Ethernet \b loopback \b plugs are available from different vendors that fulfill this purpose.
111 \defgroup eth_tests Tests
117 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
119 \brief Function: ETH_MAC_GetCapabilities
121 The test function \b ETH_MAC_GetCapabilities verifies the Ethernet MAC function \b GetCapabilities.
123 void ETH_MAC_GetCapabilities (void) {
124 /* Get ETH_MAC capabilities */
125 capab = eth_mac->GetCapabilities();
126 TEST_ASSERT(&capab != NULL);
129 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
131 \brief Function: ETH_MAC_Initialization
133 The test function \b ETH_MAC_Initialization verifies the Ethernet MAC functions in the following order:
134 - \b Initialize without callback
136 - \b Initialize with callback if supported
139 void ETH_MAC_Initialization (void) {
141 /* Initialize without callback */
142 TEST_ASSERT(eth_mac->Initialize(NULL) == ARM_DRIVER_OK);
145 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
147 /* Initialize with callback if supported */
148 TEST_ASSERT(eth_mac->Initialize((capab.event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK);
151 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
154 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
156 \brief Function: ETH_MAC_CheckInvalidInit
158 The test function \b ETH_MAC_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
160 - \b PowerControl with Power off
161 - \b PowerControl with Power on
163 - \b PowerControl with Power off
166 void ETH_MAC_CheckInvalidInit (void) {
169 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
172 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
174 /* Try to power on */
175 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
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);
182 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
185 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
188 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
190 \brief Function: ETH_MAC_PowerControl
192 The test function \b ETH_MAC_PowerControl verifies the Ethernet MAC \b PowerControl function with the sequence:
195 - Set bus speed \token{10M}
196 - Set bus speed \token{100M}
197 - Set bus speed \token{1G}
201 void ETH_MAC_PowerControl (void) {
204 /* Initialize with callback if supported */
205 TEST_ASSERT(eth_mac->Initialize((eth_mac->GetCapabilities().event_rx_frame) ? ETH_DrvEvent : NULL) == ARM_DRIVER_OK);
208 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
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); }
216 TEST_ASSERT(eth_mac->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
219 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
222 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
224 \brief Function: ETH_MAC_SetBusSpeed
226 The test function \b ETH_MAC_SetBusSpeed verifies the Ethernet MAC \b Control function with the sequence:
229 - Set bus speed \token{10M}
230 - Set bus speed \token{100M}
231 - Set bus speed \token{1G}
235 void ETH_MAC_SetBusSpeed (void) {
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);
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); }
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); }
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); }
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);
262 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
264 \brief Function: ETH_MAC_Config_Mode
266 The test function \b ETH_MAC_Config_Mode verifies the Ethernet MAC \b Control function with the sequence:
274 void ETH_MAC_Config_Mode (void) {
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);
280 /* Set full duplex */
281 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_FULL)== ARM_DRIVER_OK);
283 /* Set half duplex */
284 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_HALF)== ARM_DRIVER_OK);
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);
291 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
293 \brief Function: ETH_MAC_Config_CommonParams
295 The test function \b ETH_MAC_Config_CommonParams verifies the Ethernet MAC \b Control function with the sequence:
298 - Configure Ethernet MAC bus
300 - Configure transmitter
304 void ETH_MAC_Config_CommonParams (void) {
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);
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);
314 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
316 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
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);
323 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
325 \brief Function: ETH_PHY_Initialization
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
330 void ETH_PHY_Initialization (void) {
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);
337 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
340 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
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);
347 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
349 \brief Function: ETH_PHY_CheckInvalidInit
351 The test function \b ETH_PHY_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
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
360 void ETH_PHY_CheckInvalidInit (void) {
363 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
366 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
369 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
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);
375 /* Try to initialize without read and write functions */
376 TEST_ASSERT(eth_phy->Initialize(NULL, NULL) != ARM_DRIVER_OK);
379 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
382 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
385 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
387 \brief Function: ETH_PHY_PowerControl
389 The test function \b ETH_PHY_PowerControl verifies the Ethernet PHY \b PowerControl function with the sequence:
396 void ETH_PHY_PowerControl (void) {
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);
404 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
407 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
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); }
415 TEST_ASSERT(eth_phy->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
418 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
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);
425 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
427 \brief Function: ETH_PHY_Config
429 The test function \b ETH_PHY_Config verifies the PHY functions
437 void ETH_PHY_Config (void) {
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);
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);
447 /* Configure ETH_PHY bus*/
448 TEST_ASSERT(eth_phy->SetInterface (capab.media_interface) == ARM_DRIVER_OK);
450 TEST_ASSERT(eth_phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
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);
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);
461 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
463 \brief Function: ETH_Loopback_Transfer
465 The test function \b ETH_Loopback_Transfer verifies data transfer via Ehernet with the following sequence:
469 - Ethernet connection
470 - Set output buffer pattern
471 - Transfer data chunks
472 - Set output buffer with random data
473 - Transfer data chunks
477 void ETH_Loopback_Transfer (void) {
479 uint8_t pattern[] = BUFFER_PATTERN;
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);
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);
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");
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];
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);
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);
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();
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);
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);
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);
561 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
563 \brief Function: ETH_MAC_PTP_ControlTimer
565 The test function \b ETH_MAC_PTP_ControlTimer verifies the PTP ControlTimer function with the sequence:
576 void ETH_MAC_PTP_ControlTimer (void) {
577 ARM_ETH_MAC_TIME time1, time2;
578 int64_t t1ns, t2ns, t, overhead;
581 /* Get capabilities */
582 if (!eth_mac->GetCapabilities().precision_timer) {
583 TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
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);
589 /* Set Time -------------------------------------------------------------------------------- */
592 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
594 /* Check System Time */
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 is %lldns from expected", t);
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);
617 /* Check System Time after adjusting clock */
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);
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;
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);
634 /* Measure time overhead for increment/decrement calls ------------------------------------- */
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;
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);
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;
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);
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);
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;
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);
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);
684 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_ALARM, &time1) == ARM_DRIVER_OK);
686 /* Check alarm event after 999ms */
688 if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) != 0) {
689 TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event triggered too early");
692 /* Check alarm event after 1001ms */
694 if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) == 0) {
695 TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event timeout");
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);
704 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
706 \brief Function: ETH_Loopback_PTP
708 The test function \b ETH_Loopback_PTP verifies the Precision Time Protocol functions ControlTimer, GetRxFrameTime and
709 GetTxFrameTime with the sequence:
719 void ETH_Loopback_PTP (void) {
720 ARM_ETH_MAC_TIME time1, time2;
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
737 const uint32_t PTP_frame_len = sizeof(PTP_frame);
739 /* Get capabilities */
740 if (!eth_mac->GetCapabilities().precision_timer) {
741 TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
743 /* Allocate buffer */
744 buffer_in = (uint8_t*) malloc(PTP_frame_len*sizeof(uint8_t));
745 TEST_ASSERT(buffer_in != NULL);
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);
762 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
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));
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");
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");
788 /* Get TX Frame Time */
789 TEST_ASSERT(eth_mac->GetTxFrameTime(&time1) == ARM_DRIVER_OK);
791 /* Get RX Frame Time */
792 TEST_ASSERT(eth_mac->GetRxFrameTime(&time2) == ARM_DRIVER_OK);
794 /* Check timestamps */
795 TEST_ASSERT((time2.sec==time1.sec)?(time2.ns>time1.ns):(time2.sec>time1.sec));
798 eth_mac->ReadFrame(buffer_in, PTP_frame_len);
799 TEST_ASSERT(memcmp(buffer_in, PTP_frame, PTP_frame_len) == 0);
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);
816 // end of group dv_eth