2 * Copyright (c) 2015-2025 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 * -----------------------------------------------------------------------------
31 #include "DV_ETH_Config.h"
32 #include "DV_Framework.h"
34 #include "Driver_ETH_MAC.h"
35 #include "Driver_ETH_PHY.h"
38 #error Please update DV_ETH_Config.h
43 // Ethernet PTP time definitions
44 #define PTP_S_NS 1000000000U
45 #define PTP_TIME_REF ETH_PTP_TIME_REF
46 #define PTP_TIME_REF_NS ETH_PTP_TIME_REF*1000000U
48 static const ARM_ETH_MAC_ADDR mac_addr = {0x02, 0x30, 0x05, 0x1D, 0x1E, 0x27};
49 static const ARM_ETH_MAC_ADDR mac_bcast = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
50 static const ARM_ETH_MAC_ADDR mac_mcast[6] ={{0x01, 0x00, 0x5E, 0x00, 0x00, 0x01},
51 {0x01, 0x00, 0x5E, 0x00, 0x00, 0x02},
52 {0x01, 0x00, 0x5E, 0x7F, 0xFF, 0xFF},
53 {0x33, 0x33, 0x00, 0x00, 0x00, 0x01},
54 {0x33, 0x33, 0x00, 0x00, 0x00, 0x02},
55 {0x33, 0x33, 0xFF, 0xFF, 0xFF, 0xFF}};
57 // Register Driver_ETH_MAC# Driver_ETH_PHY#
58 extern ARM_DRIVER_ETH_MAC CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
59 extern ARM_DRIVER_ETH_PHY CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
61 static ARM_DRIVER_ETH_MAC *eth_mac;
62 static ARM_DRIVER_ETH_PHY *eth_phy;
63 static ARM_ETH_MAC_CAPABILITIES capab;
64 static ARM_ETH_MAC_SignalEvent_t cb_event;
67 static volatile uint8_t phy_power;
68 static volatile uint8_t mac_lockup;
71 // Allocated buffer pointers
72 static uint8_t *buffer_out;
73 static uint8_t *buffer_in;
76 static uint8_t volatile Event;
79 static void ETH_DrvEvent (uint32_t event) {
84 static int32_t ETH_RunTransfer (const uint8_t *out, uint8_t *in, uint32_t len, uint32_t frag) {
87 Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;
89 // Send the entire frame at once
90 eth_mac->SendFrame(out, len, 0);
93 // Split the frame into two fragments
94 eth_mac->SendFrame(out, frag, ARM_ETH_MAC_TX_FRAME_FRAGMENT);
95 eth_mac->SendFrame(out+frag, len-frag, 0);
100 // Wait for RX event or run the polling mode
101 if ((Event & ARM_ETH_MAC_EVENT_RX_FRAME) || !capab.event_rx_frame) {
102 size = eth_mac->GetRxFrameSize();
104 if ((size < 14) || (size > 14+ETH_MTU)) {
105 eth_mac->ReadFrame(NULL, 0U);
106 return ARM_DRIVER_ERROR;
108 eth_mac->ReadFrame(in, size);
109 return ARM_DRIVER_OK;
113 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT*1000));
115 return ARM_DRIVER_ERROR_TIMEOUT;
118 #define ETH_CheckAddressFilter() ETH_CheckFilter(0)
119 #define ETH_CheckVlanFilter() ETH_CheckFilter(1)
121 // Check multicast address and VLAN filtering support
122 static int32_t ETH_CheckFilter (int32_t vlan) {
125 eth_mac->Initialize(cb_event);
126 eth_mac->PowerControl(ARM_POWER_FULL);
127 retv = (!vlan) ? eth_mac->SetAddressFilter(NULL, 0) :
128 eth_mac->Control (ARM_ETH_MAC_VLAN_FILTER, 0);
129 eth_mac->PowerControl(ARM_POWER_OFF);
130 eth_mac->Uninitialize();
135 // Initialize MAC driver wrapper for RMII interface
136 static int32_t mac_initialize (ARM_ETH_MAC_SignalEvent_t cb_event) {
137 ARM_DRIVER_ETH_MAC *drv_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
140 return drv_mac->Initialize(cb_event);
143 // Uninitialize MAC driver wrapper for RMII interface
144 static int32_t mac_uninitialize (void) {
145 ARM_DRIVER_ETH_MAC *drv_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
148 return drv_mac->Uninitialize();
151 // MAC driver power control wrapper for RMII interface
152 static int32_t mac_power_control (ARM_POWER_STATE state) {
153 ARM_DRIVER_ETH_MAC *drv_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
154 ARM_DRIVER_ETH_PHY *drv_phy = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
157 retv = drv_mac->PowerControl(state);
158 if ((state == ARM_POWER_FULL) && (retv == ARM_DRIVER_ERROR) && (phy_power == 1U)) {
159 /* RMII solution when the PHY is a 50 MHz reference clock source */
160 /* MAC never exits soft reset when PHY is powered down (no 50 MHz) */
161 /* So turn on the power for the PHY here to prevent deadlock */
162 drv_phy->Initialize(drv_mac->PHY_Read, drv_mac->PHY_Write);
163 if (drv_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK) {
166 retv = drv_mac->PowerControl(state);
167 if (retv == ARM_DRIVER_OK) {
168 /* RMII lockup detected */
176 // PHY driver power control wrapper for RMII interface
177 static int32_t phy_power_control (ARM_POWER_STATE state) {
178 ARM_DRIVER_ETH_PHY *drv_phy = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
181 retv = drv_phy->PowerControl(state);
182 if ((state == ARM_POWER_OFF) && (retv == ARM_DRIVER_OK) && (phy_power == 2U)) {
188 /* Helper function that is called before tests start executing */
189 void ETH_DV_Initialize (void) {
190 static struct _ARM_DRIVER_ETH_MAC s_mac;
191 static struct _ARM_DRIVER_ETH_PHY s_phy;
193 eth_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
194 eth_phy = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
195 capab = eth_mac->GetCapabilities();
196 if (capab.media_interface == ARM_ETH_INTERFACE_RMII) {
197 memcpy(&s_mac, eth_mac, sizeof(s_mac));
198 memcpy(&s_phy, eth_phy, sizeof(s_phy));
199 /* Use wrapper functions in RMII interface mode */
200 s_mac.Initialize = &mac_initialize;
201 s_mac.Uninitialize = &mac_uninitialize;
202 s_mac.PowerControl = &mac_power_control;
203 s_phy.PowerControl = &phy_power_control;
209 cb_event = (capab.event_rx_frame) ? ETH_DrvEvent : NULL;
212 /* Helper function that is called after tests stop executing */
213 void ETH_DV_Uninitialize (void) {
214 eth_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
215 eth_phy = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
219 /*-----------------------------------------------------------------------------
221 *----------------------------------------------------------------------------*/
223 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
225 \defgroup dv_eth Ethernet Validation
226 \brief Ethernet driver validation
228 The Ethernet validation test performs the following checks:
229 - API interface compliance.
230 - Data communication with various transfer sizes and communication parameters.
231 - Loopback communication.
234 Loopback Communication Setup
235 ----------------------------
237 To perform loopback communication tests, it is required to connect the RX and TX lines of the Ethernet cable together:
239 - TX+ (Pin 1) with RX+ (Pin 3) and
240 - TX- (Pin 2) with RX- (Pin 6)
242 \image html ethernet_loopback.png
244 Various \b Ethernet \b loopback \b plugs are available from different vendors that fulfill this purpose.
246 \defgroup eth_tests Tests
252 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
254 \brief Function: Function ETH_MAC_GetVersion
256 The function \b ETH_MAC_GetVersion verifies the Ethernet MAC \b GetVersion function.
258 void ETH_MAC_GetVersion (void) {
259 ARM_DRIVER_VERSION ver;
261 ver = eth_mac->GetVersion();
263 TEST_ASSERT((ver.api >= ARM_DRIVER_VERSION_MAJOR_MINOR(1UL,0UL)) && (ver.drv >= ARM_DRIVER_VERSION_MAJOR_MINOR(1UL,0UL)));
265 snprintf(str,sizeof(str),"[INFO] API version %d.%d, Driver version %d.%d",(ver.api>>8),(ver.api&0xFFU),(ver.drv>>8),(ver.drv&0xFFU));
269 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
271 \brief Function: ETH_MAC_GetCapabilities
273 The function \b ETH_MAC_GetCapabilities verifies the Ethernet MAC \b GetCapabilities function.
275 void ETH_MAC_GetCapabilities (void) {
276 ARM_ETH_MAC_CAPABILITIES cap;
278 /* Get ETH_MAC capabilities */
279 cap = eth_mac->GetCapabilities();
281 TEST_ASSERT_MESSAGE((cap.reserved == 0U), "[FAILED] Capabilities reserved field must be 0");
284 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
286 \brief Function: ETH_MAC_Initialization
288 The function \b ETH_MAC_Initialization verifies the Ethernet MAC functions in the following order:
289 - \b Initialize without callback
291 - \b Initialize with callback if supported
294 void ETH_MAC_Initialization (void) {
296 /* Initialize without callback */
297 TEST_ASSERT(eth_mac->Initialize(NULL) == ARM_DRIVER_OK);
300 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
302 /* Initialize with callback if supported */
303 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
306 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
309 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
311 \brief Function: ETH_MAC_CheckInvalidInit
313 The function \b ETH_MAC_CheckInvalidInit verifies the driver behavior when receiving an invalid initialization sequence:
315 - \b PowerControl with Power off
316 - \b PowerControl with Power on
318 - \b PowerControl with Power off
321 void ETH_MAC_CheckInvalidInit (void) {
324 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
327 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
329 /* Try to power on */
330 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) != ARM_DRIVER_OK);
332 /* Try to set configuration */
333 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
334 ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL) != ARM_DRIVER_OK);
337 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
340 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
343 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
345 \brief Function: ETH_MAC_PowerControl
347 The function \b ETH_MAC_PowerControl verifies the Ethernet MAC \b PowerControl function with the sequence:
354 void ETH_MAC_PowerControl (void) {
357 /* Initialize with callback if supported */
358 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
361 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
364 retv = eth_mac->PowerControl(ARM_POWER_LOW);
365 if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
366 else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
369 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
372 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
375 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
377 \brief Function: ETH_MAC_MacAddress
379 The function \b ETH_MAC_MacAddress verifies the Ethernet MAC \b GetMacAddress and \b SetMacAddress functions
383 - Set Ethernet MAC Address
384 - Get Ethernet MAC Address
388 void ETH_MAC_MacAddress (void) {
389 ARM_ETH_MAC_ADDR my_addr;
391 /* Initialize with callback if supported and power on */
392 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
393 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
395 /* Set MAC Address */
396 TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
398 /* Verify MAC Address */
399 memset(&my_addr, 0, 6);
400 TEST_ASSERT(eth_mac->GetMacAddress(&my_addr) == ARM_DRIVER_OK);
401 if (memcmp(&mac_addr, &my_addr, 6) != 0) {
402 TEST_FAIL_MESSAGE("[FAILED] Verify MAC address");
406 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
409 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
412 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
414 \brief Function: ETH_MAC_SetBusSpeed
416 The function \b ETH_MAC_SetBusSpeed verifies the Ethernet MAC \b Control function with the sequence:
419 - Set bus speed \token{10M}
420 - Set bus speed \token{100M}
421 - Set bus speed \token{1G}
425 void ETH_MAC_SetBusSpeed (void) {
428 /* Initialize with callback if supported and power on */
429 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
430 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
432 /* Set bus speed 10M */
433 retv = eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_10M);
434 if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 10M is not supported"); }
435 else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
437 /* Set bus speed 100M */
438 retv = eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M);
439 if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 100M is not supported"); }
440 else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
442 /* Set bus speed 1G */
443 retv = eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_1G);
444 if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 1G is not supported"); }
445 else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
447 /* Power off and uninitialize */
448 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
449 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
452 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
454 \brief Function: ETH_MAC_Config_Mode
456 The function \b ETH_MAC_Config_Mode verifies the Ethernet MAC \b Control function with the sequence:
464 void ETH_MAC_Config_Mode (void) {
466 /* Initialize with callback if supported and power on */
467 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
468 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
470 /* Set full duplex */
471 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_FULL) == ARM_DRIVER_OK);
473 /* Set half duplex */
474 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_HALF) == ARM_DRIVER_OK);
476 /* Power off and uninitialize */
477 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
478 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
481 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
483 \brief Function: ETH_MAC_Config_CommonParams
485 The function \b ETH_MAC_Config_CommonParams verifies the Ethernet MAC \b Control function with the sequence:
488 - Configure Ethernet MAC bus
490 - Configure transmitter
494 void ETH_MAC_Config_CommonParams (void) {
496 /* Initialize with callback if supported and power on */
497 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
498 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
500 /* Configure ETH_MAC bus*/
501 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
502 ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
504 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
506 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
508 /* Power off and uninitialize */
509 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
510 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
513 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
515 \brief Function: ETH_MAC_Control_Filtering
517 The function \b ETH_MAC_Control_Filtering verifies the Ethernet MAC \b Control function with the following sequence:
522 - Receive with broadcast disabled
524 - Receive with multicast disabled
526 - Promiscuous mode receive
531 The internal Ethernet MAC loopback is used for the test.
533 void ETH_MAC_Control_Filtering (void) {
536 /* Allocate buffers */
537 buffer_out = (uint8_t *)malloc(64);
538 TEST_ASSERT(buffer_out != NULL);
539 if (buffer_out == NULL) return;
540 buffer_in = (uint8_t *)malloc(64);
541 TEST_ASSERT(buffer_in != NULL);
542 if (buffer_in == NULL) { free(buffer_out); return; }
544 /* Initialize, power on and configure MAC and PHY */
545 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
546 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
547 TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
548 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M |
549 ARM_ETH_MAC_DUPLEX_FULL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
550 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
551 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
553 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
554 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
555 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
556 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
558 /* Set Ethernet header */
559 memcpy(&buffer_out[6], &mac_addr, 6);
563 for (i = 14; i < 64; i++) {
564 buffer_out[i] = i + 'A' - 14;
567 /* Broadcast receive */
568 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK |
569 ARM_ETH_MAC_ADDRESS_BROADCAST) == ARM_DRIVER_OK);
570 memcpy(&buffer_out[0], &mac_bcast, 6);
571 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
572 TEST_FAIL_MESSAGE("[FAILED] Receive broadcast");
575 /* Receive with broadcast disabled */
576 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
577 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
578 TEST_MESSAGE("[WARNING] Broadcast receive not disabled");
581 /* Multicast receive */
582 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK |
583 ARM_ETH_MAC_ADDRESS_MULTICAST) == ARM_DRIVER_OK);
584 for (i = 0; i < 6; i++) {
585 memcpy(&buffer_out[0], &mac_mcast[i], 6);
586 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
587 snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
588 TEST_FAIL_MESSAGE(str);
592 /* Receive with multicast disabled */
593 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
594 memcpy(&buffer_out[0], &mac_mcast[0], 6);
595 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
596 TEST_MESSAGE("[WARNING] Multicast receive not disabled");
599 /* Unicast receive */
600 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
601 memcpy(&buffer_out[0], &mac_addr, 6);
602 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
603 TEST_FAIL_MESSAGE("[FAILED] Receive unicast");
606 /* Promiscuous mode receive */
607 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK |
608 ARM_ETH_MAC_ADDRESS_ALL) == ARM_DRIVER_OK);
609 /* Test broadcast receive */
610 memcpy(&buffer_out[0], &mac_bcast, 6);
611 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
612 TEST_FAIL_MESSAGE("[FAILED] Receive broadcast in promiscuous mode");
614 /* Test multicast receive */
615 memcpy(&buffer_out[0], &mac_mcast[0], 6);
616 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
617 TEST_FAIL_MESSAGE("[FAILED] Receive multicast in promiscuous mode");
619 /* Test unicast receive */
620 memcpy(&buffer_out[0], &mac_addr, 6);
621 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
622 TEST_FAIL_MESSAGE("[FAILED] Receive unicast in promiscuous mode");
625 /* Power off and uninitialize */
626 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
627 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
628 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
629 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
636 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
638 \brief Function: ETH_MAC_SetAddressFilter
640 The function \b ETH_MAC_SetAddressFilter verifies the Ethernet MAC \b SetAddressFilter function with the following sequence:
644 - Receive one multicast address
645 - Receive two multicast addresses
646 - Receive three multicast addresses
647 - Receive four multicast addresses
648 - Receive six multicast addresses
653 The internal Ethernet MAC loopback is used for the test.
655 void ETH_MAC_SetAddressFilter (void) {
658 if (ETH_CheckAddressFilter() == ARM_DRIVER_ERROR_UNSUPPORTED) {
659 /* Multicast address filtering not supported */
660 TEST_MESSAGE("[WARNING] Multicast address filtering is not supported");
664 /* Allocate buffers */
665 buffer_out = (uint8_t *)malloc(64);
666 TEST_ASSERT(buffer_out != NULL);
667 if (buffer_out == NULL) return;
668 buffer_in = (uint8_t *)malloc(64);
669 TEST_ASSERT(buffer_in != NULL);
670 if (buffer_in == NULL) { free(buffer_out); return; }
672 /* Initialize, power on and configure MAC and PHY */
673 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
674 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
675 TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
676 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M |
677 ARM_ETH_MAC_DUPLEX_FULL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
678 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
679 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
681 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
682 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
683 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
684 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
686 /* Set Ethernet header */
687 memcpy(&buffer_out[6], &mac_addr, 6);
691 for (i = 14; i < 64; i++) {
692 buffer_out[i] = i + 'A' - 14;
695 /* Receive one multicast address */
696 TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 1) == ARM_DRIVER_OK);
698 memcpy(&buffer_out[0], &mac_mcast[0], 6);
699 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
700 /* Error, enabled multicast address not received */
701 TEST_FAIL_MESSAGE("[FAILED] Receive multicast 0 address");
704 for (i = 1; i < 6; i++) {
705 memcpy(&buffer_out[0], &mac_mcast[i], 6);
706 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
707 /* Warning, disabled multicast address received */
708 snprintf(str,sizeof(str),"[WARNING] Receive multicast %d address",i);
713 /* Receive two multicast addresses */
714 TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 2) == ARM_DRIVER_OK);
716 for (i = 0; i < 2; i++) {
717 memcpy(&buffer_out[0], &mac_mcast[i], 6);
718 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
719 /* Error, enabled multicast address not received */
720 snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
721 TEST_FAIL_MESSAGE(str);
726 memcpy(&buffer_out[0], &mac_mcast[i], 6);
727 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
728 /* Warning, disabled multicast address received */
729 snprintf(str,sizeof(str),"[WARNING] Receive multicast %d address",i);
734 /* Receive three multicast addresses */
735 TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 3) == ARM_DRIVER_OK);
737 for (i = 0; i < 3; i++) {
738 memcpy(&buffer_out[0], &mac_mcast[i], 6);
739 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
740 /* Error, enabled multicast address not received */
741 snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
742 TEST_FAIL_MESSAGE(str);
747 memcpy(&buffer_out[0], &mac_mcast[i], 6);
748 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
749 /* Warning, disabled multicast address received */
750 snprintf(str,sizeof(str),"[WARNING] Receive multicast %d address",i);
755 /* Receive four multicast addresses */
756 TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 4) == ARM_DRIVER_OK);
758 for (i = 0; i < 4; i++) {
759 memcpy(&buffer_out[0], &mac_mcast[i], 6);
760 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
761 /* Error, enabled multicast address not received */
762 snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
763 TEST_FAIL_MESSAGE(str);
768 memcpy(&buffer_out[0], &mac_mcast[i], 6);
769 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
770 /* Warning, disabled multicast address received */
771 snprintf(str,sizeof(str),"[WARNING] Receive multicast %d address",i);
776 /* Receive all multicast addresses */
777 TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 6) == ARM_DRIVER_OK);
779 for (i = 0; i < 6; i++) {
780 memcpy(&buffer_out[0], &mac_mcast[i], 6);
781 if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
782 /* Error, enabled multicast address not received */
783 snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
784 TEST_FAIL_MESSAGE(str);
788 /* Power off and uninitialize */
789 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
790 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
791 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
792 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
799 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
801 \brief Function: ETH_MAC_VLAN_Filter
803 The function \b ETH_MAC_VLAN_Filter verifies the Ethernet MAC Virtual LAN filtering with the following sequence:
807 - Transfer VLAN packets
808 - Receive VLAN packets
813 The internal Ethernet MAC loopback is used for the test.
815 void ETH_MAC_VLAN_Filter (void) {
816 const uint8_t IP_frame[] = {
817 0x01,0x00,0x5e,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x00,0x00,
818 0x08,0x00,0x45,0x00,0x00,0x1c,0x65,0x51,0x00,0x00,0x01,0x02,0xb2,0xe3,0xc0,0xa8,
819 0x01,0x02,0xe0,0x00,0x00,0x01,0x11,0x64,0xee,0x9b,0x00,0x00,0x00,0x00,0x00,0x00,
820 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
822 const uint16_t test_id[] = { 1,2,100,500,1000,1005,1006,1500,2000,4000,4093 };
823 const uint16_t vlan_id[] = { 1,20,100,1000,2000,4093 };
826 if (ETH_CheckVlanFilter() == ARM_DRIVER_ERROR_UNSUPPORTED) {
827 /* VLAN tagged frame filtering not supported */
828 TEST_MESSAGE("[WARNING] VLAN filtering is not supported");
832 /* Allocate buffers */
833 buffer_out = (uint8_t *)malloc(64);
834 TEST_ASSERT(buffer_out != NULL);
835 if (buffer_out == NULL) return;
836 buffer_in = (uint8_t *)malloc(64);
837 TEST_ASSERT(buffer_in != NULL);
838 if (buffer_in == NULL) { free(buffer_out); return; }
840 /* Initialize, power on and configure MAC and PHY */
841 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
842 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
843 TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
844 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M |
845 ARM_ETH_MAC_DUPLEX_FULL | ARM_ETH_MAC_ADDRESS_BROADCAST) == ARM_DRIVER_OK);
846 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
847 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
849 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
850 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
851 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
852 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
854 /* Set Ethernet frame */
855 memcpy (buffer_out, IP_frame, sizeof (IP_frame));
856 memcpy (&buffer_out[6], &mac_addr, 6);
858 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
859 ARM_ETH_MAC_ADDRESS_MULTICAST | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
861 for (i = 0; i < ARRAY_SIZE(vlan_id); i++) {
862 TEST_ASSERT(eth_mac->Control (ARM_ETH_MAC_VLAN_FILTER,
863 ARM_ETH_MAC_VLAN_FILTER_ID_ONLY | vlan_id[i]) == ARM_DRIVER_OK);
864 for (j = 0; j < ARRAY_SIZE(test_id); j++) {
866 /* Set VLAN ID tag */
867 buffer_out[14] = (test_id[j] >> 8) & 0xFF;
868 buffer_out[15] = test_id[j] & 0xFF;
869 retv = ETH_RunTransfer(buffer_out, buffer_in, 64, 0);
870 if (((test_id[j] == vlan_id[i]) && (retv != ARM_DRIVER_OK)) ||
871 ((test_id[j] != vlan_id[i]) && (retv == ARM_DRIVER_OK))) {
872 snprintf(str,sizeof(str),"[FAILED] VLAN tag %d",vlan_id[i]);
873 TEST_FAIL_MESSAGE(str);
880 /* Power off and uninitialize */
881 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
882 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
883 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
884 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
891 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
893 \brief Function: ETH_MAC_SignalEvent
895 The function \b ETH_MAC_SignalEvent verifies the Ethernet MAC interrupt operation with the sequence:
899 - Configure transmitter
900 - Set output buffer pattern
901 - Send data and check receive interrupts
906 The internal Ethernet MAC loopback is used for the test.
908 void ETH_MAC_SignalEvent (void) {
911 if (!capab.event_rx_frame) {
912 TEST_MESSAGE("[WARNING] Interrupt mode is not supported");
916 /* Allocate buffer */
917 buffer_out = (uint8_t *)malloc(64);
918 TEST_ASSERT(buffer_out != NULL);
919 if (buffer_out == NULL) return;
921 /* Initialize, power on and configure MAC */
922 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
923 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
924 TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
925 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
926 ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
927 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
928 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
930 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
931 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
932 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
933 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
935 /* Set Ethernet header */
936 memcpy(&buffer_out[0], &mac_bcast, 6);
937 memcpy(&buffer_out[6], &mac_addr, 6);
941 for (i = 14; i < 64; i++) {
942 buffer_out[i] = i + 'A' - 14;
945 Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;
946 TEST_ASSERT(eth_mac->SendFrame(buffer_out, 64, 0) == ARM_DRIVER_OK);
948 /* Wait for RX interrupt event */
949 tick = GET_SYSTICK();
951 if (Event & ARM_ETH_MAC_EVENT_RX_FRAME) {
955 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT*1000));
957 if (!(Event & ARM_ETH_MAC_EVENT_RX_FRAME)) {
958 TEST_FAIL_MESSAGE("[FAILED] Interrupt mode not working");
961 /* Power off and uninitialize */
962 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
963 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
964 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
965 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
968 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
970 \brief Function: Function ETH_PHY_GetVersion
972 The function \b ETH_PHY_GetVersion verifies the Ethernet PHY \b GetVersion function.
974 void ETH_PHY_GetVersion (void) {
975 ARM_DRIVER_VERSION ver;
977 ver = eth_phy->GetVersion();
979 TEST_ASSERT((ver.api >= ARM_DRIVER_VERSION_MAJOR_MINOR(1UL,0UL)) && (ver.drv >= ARM_DRIVER_VERSION_MAJOR_MINOR(1UL,0UL)));
981 snprintf(str,sizeof(str),"[INFO] API version %d.%d, Driver version %d.%d",(ver.api>>8),(ver.api&0xFFU),(ver.drv>>8),(ver.drv&0xFFU));
985 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
987 \brief Function: ETH_PHY_Initialization
989 The function \b ETH_PHY_Initialization verifies the Ethernet PHY functions in the following order:
990 - \b Initialize with read and write functions
992 void ETH_PHY_Initialization (void) {
994 /* MAC Initialize and power on */
995 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
996 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
999 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1002 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1004 /* MAC Power off and uninitialize */
1005 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1006 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1009 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1011 \brief Function: ETH_PHY_CheckInvalidInit
1013 The function \b ETH_PHY_CheckInvalidInit verifies the driver behavior when receiving an invalid initialization sequence:
1015 - \b PowerControl with Power off
1016 - \b PowerControl with Power on
1017 - \b SetInterface to configure the Ethernet PHY bus
1018 - \b SetMode to configure the Ethernet PHY bus
1019 - \b PowerControl with Power off
1022 void ETH_PHY_CheckInvalidInit (void) {
1025 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1028 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) != ARM_DRIVER_OK);
1030 /* Try to power on */
1031 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) != ARM_DRIVER_OK);
1033 /* Try to configure ETH_PHY bus*/
1034 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) != ARM_DRIVER_OK);
1035 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) != ARM_DRIVER_OK);
1037 /* Try to initialize without read and write functions */
1038 TEST_ASSERT(eth_phy->Initialize(NULL, NULL) != ARM_DRIVER_OK);
1041 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) != ARM_DRIVER_OK);
1044 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1047 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1049 \brief Function: ETH_PHY_PowerControl
1051 The function \b ETH_PHY_PowerControl verifies the Ethernet PHY \b PowerControl function with the sequence:
1060 When the Ethernet PHY is the 50 MHz clock source for the MAC in RMII mode, the MAC may lock up if the PHY power is off
1061 and therefore not generating a reference clock.
1063 void ETH_PHY_PowerControl (void) {
1066 /* MAC Initialize and power on */
1067 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1068 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1071 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1074 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1077 retv = eth_phy->PowerControl(ARM_POWER_LOW);
1078 if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
1079 else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
1082 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1085 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1087 /* Check RMII lockup */
1088 if ((capab.media_interface == ARM_ETH_INTERFACE_RMII) && (!mac_lockup)) {
1089 eth_mac->PowerControl(ARM_POWER_OFF);
1090 eth_mac->PowerControl(ARM_POWER_FULL);
1091 eth_phy->PowerControl(ARM_POWER_OFF);
1092 eth_phy->Uninitialize();
1095 TEST_MESSAGE("[WARNING] MAC is locked when PHY power is off");
1098 /* MAC Power off and uninitialize */
1099 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1100 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1103 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1105 \brief Function: ETH_PHY_Config
1107 The function \b ETH_PHY_Config verifies the PHY functions
1115 void ETH_PHY_Config (void) {
1117 /* MAC Initialize and power on */
1118 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1119 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1121 /* Initialize and power on */
1122 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1123 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1125 /* Configure ETH_PHY bus */
1126 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
1128 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
1130 /* Power off and uninitialize */
1131 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1132 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1134 /* MAC Power off and uninitialize */
1135 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1136 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1139 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1141 \brief Function: ETH_Loopback_Transfer
1143 The function \b ETH_Loopback_Transfer verifies data transfer via Ethernet with the following sequence:
1147 - Set output buffer pattern
1148 - Transfer data chunks
1149 - Set output buffer with random data
1150 - Transfer data chunks
1151 - Transfer data by sending in two fragments
1156 The internal Ethernet MAC loopback is used as a data loopback, so there is no need to use an external loopback cable.
1158 void ETH_Loopback_Transfer (void) {
1159 const uint16_t test_len[] = {
1160 28,36,40,44,45,46,47,48,49,50,55,60,65,70,75,80,85,90,95,100,110,120,127,128,
1161 129,140,150,160,170,180,190,196,200,220,240,250,256,270,300,325,350,375,400,
1162 425,450,475,500,511,512,513,525,550,575,600,625,650,700,750,800,850,900,950,
1163 1000,1024,1050,1100,1150,1200,1250,1300,1320,1420,1480,1490,1491,1492,1493,
1164 1494,1495,1496,1497,1498,1499,1500};
1165 const uint32_t test_num = ARRAY_SIZE(test_len);
1166 uint32_t i,cnt,tick;
1168 /* Allocate buffers, add space for Ethernet header */
1169 buffer_out = (uint8_t *)malloc(14+ETH_MTU);
1170 TEST_ASSERT(buffer_out != NULL);
1171 if (buffer_out == NULL) return;
1172 buffer_in = (uint8_t *)malloc(14+ETH_MTU);
1173 TEST_ASSERT(buffer_in != NULL);
1174 if (buffer_in == NULL) { free(buffer_out); return; }
1176 /* Initialize, power on and configure MAC */
1177 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1178 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1179 TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
1180 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
1181 ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
1182 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1183 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1185 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
1186 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
1187 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
1188 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
1190 /* Set output buffer pattern */
1191 for (i = 0; i < ETH_MTU; i+=2) {
1192 buffer_out[14+i] = 0x55;
1193 buffer_out[15+i] = 0xAA;
1196 /* Set Ethernet header */
1197 memcpy(&buffer_out[0], &mac_bcast, 6);
1198 memcpy(&buffer_out[6], &mac_addr, 6);
1200 /* Transfer data chunks */
1201 for (cnt = 0; cnt < test_num; cnt++) {
1202 /* Clear input buffer */
1203 memset(buffer_in, 0, test_len[cnt]);
1204 /* Set Ethernet type/length */
1205 buffer_out[12] = test_len[cnt] >> 8;
1206 buffer_out[13] = test_len[cnt] & 0xFF;
1207 if (ETH_RunTransfer(buffer_out, buffer_in, 14+test_len[cnt], 0) != ARM_DRIVER_OK) {
1208 snprintf(str,sizeof(str),"[FAILED] Transfer block of %d bytes",test_len[cnt]);
1209 TEST_FAIL_MESSAGE(str);
1210 } else if (memcmp(buffer_in, buffer_out, 14+test_len[cnt]) != 0) {
1211 snprintf(str,sizeof(str),"[FAILED] Verify block of %d bytes",test_len[cnt]);
1212 TEST_FAIL_MESSAGE(str);
1216 /* Set output buffer with random data */
1217 srand(GET_SYSTICK());
1218 for (i = 0; i < ETH_MTU; i++) {
1219 buffer_out[14+cnt] = (uint8_t)rand();
1222 /* Transfer data chunks */
1223 for (cnt = 0; cnt < test_num; cnt++) {
1224 /* Clear input buffer */
1225 memset(buffer_in, 0, test_len[cnt]);
1226 /* Set Ethernet type/length */
1227 buffer_out[12] = test_len[cnt] >> 8;
1228 buffer_out[13] = test_len[cnt] & 0xFF;
1229 if (ETH_RunTransfer(buffer_out, buffer_in, 14+test_len[cnt], 0) != ARM_DRIVER_OK) {
1230 snprintf(str,sizeof(str),"[FAILED] Transfer block of %d bytes",test_len[cnt]);
1231 TEST_FAIL_MESSAGE(str);
1232 } else if (memcmp(buffer_in, buffer_out, 14+test_len[cnt]) != 0) {
1233 snprintf(str,sizeof(str),"[FAILED] Verify block of %d bytes",test_len[cnt]);
1234 TEST_FAIL_MESSAGE(str);
1238 /* Block transfer in two fragments: header and data */
1239 for (cnt = 0; cnt < test_num; cnt++) {
1240 /* Clear input buffer */
1241 memset(buffer_in, 0, test_len[cnt]);
1242 /* Set Ethernet type/length */
1243 buffer_out[12] = test_len[cnt] >> 8;
1244 buffer_out[13] = test_len[cnt] & 0xFF;
1245 if (ETH_RunTransfer(buffer_out, buffer_in, 14+test_len[cnt], 0) != ARM_DRIVER_OK) {
1246 snprintf(str,sizeof(str),"[FAILED] Fragmented block transfer of %d bytes",test_len[cnt]);
1247 TEST_FAIL_MESSAGE(str);
1248 } else if (memcmp(buffer_in, buffer_out, 14+test_len[cnt]) != 0) {
1249 snprintf(str,sizeof(str),"[FAILED] Fragmented block check of %d bytes",test_len[cnt]);
1250 TEST_FAIL_MESSAGE(str);
1254 /* Power off and uninitialize */
1255 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1256 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1257 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1258 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1265 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1267 \brief Function: ETH_Loopback_External
1269 The function \b ETH_Loopback_External verifies data transfer via Ethernet with the following sequence:
1273 - Set output buffer pattern
1274 - Transfer data on PHY internal loopback
1275 - Ethernet connection
1276 - Transfer data on external cable loopback
1281 An external loopback cable is required for this test.
1283 void ETH_Loopback_External (void) {
1284 ARM_ETH_LINK_INFO info;
1285 uint32_t i,cnt,tick;
1287 /* Allocate buffers, add space for Ethernet header */
1288 buffer_out = (uint8_t *)malloc(14+ETH_MTU);
1289 TEST_ASSERT(buffer_out != NULL);
1290 if (buffer_out == NULL) return;
1291 buffer_in = (uint8_t *)malloc(14+ETH_MTU);
1292 TEST_ASSERT(buffer_in != NULL);
1293 if (buffer_in == NULL) { free(buffer_out); return; }
1295 /* Initialize, power on and configure MAC and PHY */
1296 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1297 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1298 TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
1299 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
1300 ARM_ETH_MAC_ADDRESS_BROADCAST) == ARM_DRIVER_OK);
1301 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1302 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1304 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
1305 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_SPEED_100M |
1306 ARM_ETH_PHY_DUPLEX_FULL | ARM_ETH_PHY_LOOPBACK) == ARM_DRIVER_OK);
1307 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
1308 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
1310 /* Fill output buffer */
1311 for (cnt = 0; cnt < ETH_MTU; cnt++) {
1312 buffer_out[14+cnt] = (cnt ^ 0x20) & 0x7F;
1315 /* Set Ethernet header */
1316 memcpy(&buffer_out[0], &mac_bcast, 6);
1317 memcpy(&buffer_out[6], &mac_addr, 6);
1319 /* Set Ethernet type/length */
1320 buffer_out[12] = (ETH_MTU >> 8) & 0xFF;
1321 buffer_out[13] = ETH_MTU & 0xFF;
1323 /* Check PHY internal loopback */
1324 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_SPEED_100M |
1325 ARM_ETH_PHY_DUPLEX_FULL | ARM_ETH_PHY_LOOPBACK) == ARM_DRIVER_OK);
1328 /* Clear input buffer*/
1329 memset(buffer_in, 0, 14+ETH_MTU);
1330 if (ETH_RunTransfer(buffer_out, buffer_in, 14+ETH_MTU, 0) != ARM_DRIVER_OK) {
1331 TEST_MESSAGE("[WARNING] PHY internal loopback is not active");
1332 } else if (memcmp(buffer_in, buffer_out, 14+ETH_MTU) != 0) {
1333 TEST_FAIL_MESSAGE("[FAILED] Verify received data");
1336 /* Check external cable loopback */
1337 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
1339 /* Check Ethernet link */
1340 tick = GET_SYSTICK();
1341 while (eth_phy->GetLinkState() != ARM_ETH_LINK_UP) {
1342 if ((GET_SYSTICK() - tick) >= SYSTICK_MICROSEC(ETH_LINK_TIMEOUT*1000)) {
1343 TEST_FAIL_MESSAGE("[FAILED] Link down, connect Ethernet cable");
1348 info = eth_phy->GetLinkInfo();
1349 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE,
1350 (uint32_t)info.speed << ARM_ETH_MAC_SPEED_Pos |
1351 (uint32_t)info.duplex << ARM_ETH_MAC_DUPLEX_Pos |
1352 ARM_ETH_MAC_ADDRESS_BROADCAST) == ARM_DRIVER_OK);
1354 /* Clear input buffer */
1355 memset(buffer_in, 0, 14+ETH_MTU);
1356 if (ETH_RunTransfer(buffer_out, buffer_in, 14+ETH_MTU, 0) != ARM_DRIVER_OK) {
1357 TEST_FAIL_MESSAGE("[FAILED] Transfer external cable loopback");
1358 } else if (memcmp(buffer_in, buffer_out, 14+ETH_MTU) != 0) {
1359 TEST_FAIL_MESSAGE("[FAILED] Verify received data");
1362 /* Power off and uninitialize */
1364 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1365 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1366 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1367 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1374 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1376 \brief Function: ETH_MAC_PTP_ControlTimer
1378 The function \b ETH_MAC_PTP_ControlTimer verifies the PTP \b ControlTimer function with the sequence:
1389 void ETH_MAC_PTP_ControlTimer (void) {
1390 ARM_ETH_MAC_TIME time1,time2;
1391 int64_t t,t1ns,t2ns,overhead;
1394 /* Get capabilities */
1395 if (!capab.precision_timer) {
1396 TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
1400 /* Initialize, power on and configure MAC */
1401 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1402 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1404 /* Set Time -------------------------------------------------------------------------------- */
1407 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
1409 /* Check System Time */
1411 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1412 osDelay(PTP_TIME_REF);
1413 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1415 /* Get timestamps in nanoseconds */
1416 t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1417 t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1418 t = t2ns - t1ns - PTP_TIME_REF_NS;
1420 /* Check timestamps difference */
1421 if (llabs(t) > ETH_PTP_TOLERANCE) {
1422 snprintf(str,sizeof(str),"[WARNING] PTP measured time is %lldns from expected", t);
1426 /* Adjust clock - Set correction factor ---------------------------------------------------- */
1427 /* Calculate rate and convert it to q31 format */
1428 rate = (double)PTP_TIME_REF_NS / (t2ns-t1ns);
1429 time1.ns = (uint32_t)(0x80000000U*rate);
1430 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_ADJUST_CLOCK, &time1) == ARM_DRIVER_OK);
1432 /* Check System Time after adjusting clock */
1434 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1435 osDelay(PTP_TIME_REF);
1436 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1438 /* Get timestamps in nanoseconds */
1439 t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1440 t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1441 t = t2ns - t1ns - PTP_TIME_REF_NS;
1443 /* Check timestamps difference */
1444 if (llabs(t) > ETH_PTP_TOLERANCE) {
1445 snprintf(str,sizeof(str),"[WARNING] PTP measured time with adj clk is %lldns from expected", t);
1449 /* Measure time overhead for increment/decrement calls ------------------------------------- */
1452 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1453 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_INC_TIME, &time2) == ARM_DRIVER_OK);
1454 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1455 t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1456 t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1457 overhead = t2ns - t1ns;
1459 /* Increment time -------------------------------------------------------------------------- */
1460 time2.sec = PTP_TIME_REF/1000U;
1461 time2.ns = (PTP_TIME_REF-time2.sec*1000U)*1000000U;
1462 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1463 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_INC_TIME, &time2) == ARM_DRIVER_OK);
1464 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1466 /* Get timestamps in nanoseconds */
1467 t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1468 t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1469 t = t2ns - t1ns - PTP_TIME_REF_NS - overhead;
1471 /* Check timestamps difference */
1472 if (llabs(t) > ETH_PTP_TOLERANCE) {
1473 snprintf(str,sizeof(str),"[WARNING] PTP incremented time is %lldns from expected", t);
1477 /* Decrement time -------------------------------------------------------------------------- */
1478 time2.sec = PTP_TIME_REF/1000U;
1479 time2.ns = (PTP_TIME_REF-time2.sec*1000U)*1000000U;
1480 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1481 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_DEC_TIME, &time2) == ARM_DRIVER_OK);
1482 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1484 /* Get timestamps in nanoseconds */
1485 t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1486 t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1487 t = t2ns - t1ns + PTP_TIME_REF_NS - overhead;
1489 /* Check timestamps difference */
1490 if (llabs(t) > ETH_PTP_TOLERANCE) {
1491 snprintf(str,sizeof(str),"[WARNING] PTP decremented time is %lldns from expected", t);
1495 /* Set Alarm (1s) -------------------------------------------------------------------------- */
1496 Event &= ~ARM_ETH_MAC_EVENT_TIMER_ALARM;
1497 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1499 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_ALARM, &time1) == ARM_DRIVER_OK);
1501 /* Check alarm event after 999ms */
1503 if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) != 0) {
1504 TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event triggered too early");
1507 /* Check alarm event after 1001ms */
1509 if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) == 0) {
1510 TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event timeout");
1513 /* Power off and uninitialize */
1514 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1515 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1518 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1520 \brief Function: ETH_Loopback_PTP
1522 The function \b ETH_Loopback_PTP verifies the Precision Time Protocol functions \b ControlTimer, \b GetRxFrameTime and
1523 \b GetTxFrameTime with the sequence:
1534 The internal Ethernet MAC loopback is used as the data loopback.
1536 void ETH_Loopback_PTP (void) {
1537 ARM_ETH_MAC_TIME time1,time2;
1540 // PTP over Ethernet IPv4 sample frame
1541 const uint8_t PTP_frame[] = {
1542 0x01,0x00,0x5e,0x00,0x01,0x81,0x02,0x30,0x05,0x1d,0x1e,0x27,0x08,0x00,0x45,0x00,
1543 0x00,0x98,0x00,0x5d,0x40,0x00,0x01,0x11,0x29,0x68,0x0a,0x0a,0x64,0x05,0xe0,0x00,
1544 0x01,0x81,0x01,0x3f,0x01,0x3f,0x00,0x84,0xc0,0x7b,0x00,0x01,0x00,0x01,0x5f,0x44,
1545 0x46,0x4c,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
1546 0x00,0x30,0x05,0x1d,0x1e,0x27,0x00,0x01,0x00,0x5e,0x00,0x00,0x00,0x08,0x00,0x00,
1547 0x00,0x00,0x45,0x5b,0x0a,0x38,0x0e,0xb9,0x26,0x58,0x00,0x00,0x00,0x00,0x00,0x01,
1548 0x00,0x30,0x05,0x1d,0x1e,0x27,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x04,0x44,0x46,
1549 0x4c,0x54,0x00,0x00,0xf0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
1550 0xf0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x44,0x46,0x4c,0x54,0x00,0x01,
1551 0x00,0x30,0x05,0x1d,0x1e,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1552 0x00,0x00,0x00,0x00,0x00,0x00
1554 const uint32_t PTP_frame_len = sizeof(PTP_frame);
1556 /* Get capabilities */
1557 if (!capab.precision_timer) {
1558 TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
1562 /* Allocate buffer */
1563 buffer_in = (uint8_t *)malloc(PTP_frame_len);
1564 TEST_ASSERT(buffer_in != NULL);
1565 if (buffer_in == NULL) return;
1567 /* Initialize, power on and configure MAC and PHY */
1568 TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1569 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1570 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
1571 ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
1572 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
1573 TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
1574 TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1575 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1577 TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
1578 TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
1583 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
1585 /* Check timestamps - verify if control timer is running */
1586 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1587 TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1588 TEST_ASSERT((time2.sec==time1.sec)?(time2.ns>time1.ns):(time2.sec>time1.sec));
1590 /* Transfer frame */
1591 TEST_ASSERT(eth_mac->SendFrame(PTP_frame, PTP_frame_len, ARM_ETH_MAC_TX_FRAME_TIMESTAMP) == ARM_DRIVER_OK);
1592 tick = GET_SYSTICK();
1593 while (eth_mac->GetRxFrameSize() == 0) {
1594 if ((GET_SYSTICK() - tick) >= SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT*1000)) {
1595 TEST_FAIL_MESSAGE("[FAILED] Transfer timeout");
1600 /* Get TX Frame Time */
1601 TEST_ASSERT(eth_mac->GetTxFrameTime(&time1) == ARM_DRIVER_OK);
1603 /* Get RX Frame Time */
1604 TEST_ASSERT(eth_mac->GetRxFrameTime(&time2) == ARM_DRIVER_OK);
1606 /* Check timestamps */
1607 TEST_ASSERT((time2.sec==time1.sec) ? (time2.ns>time1.ns) : (time2.sec>time1.sec));
1610 eth_mac->ReadFrame(buffer_in, PTP_frame_len);
1611 TEST_ASSERT(memcmp(buffer_in, PTP_frame, PTP_frame_len) == 0);
1613 /* Power off and uninitialize */
1614 TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1615 TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1616 TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1617 TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1627 // end of group dv_eth