]> begriffs open source - cmsis-driver-validation/blob - Source/DV_ETH.c
Update pdsc file (#15)
[cmsis-driver-validation] / Source / DV_ETH.c
1 /*
2  * Copyright (c) 2015-2023 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * -----------------------------------------------------------------------------
19  *
20  * Project:     CMSIS-Driver Validation
21  * Title:       Ethernet (ETH) Driver Validation tests
22  *
23  * -----------------------------------------------------------------------------
24  */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "cmsis_dv.h"
31 #include "DV_ETH_Config.h"
32 #include "DV_Framework.h"
33
34 #include "Driver_ETH_MAC.h"
35 #include "Driver_ETH_PHY.h"
36
37 #ifdef BUFFER_PATTERN
38 #error Please update DV_ETH_Config.h
39 #endif
40
41 #define ETH_MTU          1500
42
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
47
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}};
56
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);
60
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;
65
66 // Local variables
67 static volatile uint8_t phy_power;
68 static volatile uint8_t mac_lockup;
69 static char str[128];
70
71 // Allocated buffer pointers
72 static uint8_t *buffer_out;
73 static uint8_t *buffer_in;
74
75 // Event flags
76 static uint8_t volatile Event;
77
78 // Ethernet event
79 static void ETH_DrvEvent (uint32_t event) {
80   Event |= event;
81 }
82
83 // Ethernet transfer
84 static int32_t ETH_RunTransfer (const uint8_t *out, uint8_t *in, uint32_t len, uint32_t frag) {
85   uint32_t tick,size;
86
87   Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;
88   if (frag == 0U) {
89     // Send the entire frame at once
90     eth_mac->SendFrame(out, len, 0);
91   }
92   else {
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);
96   }
97
98   tick = GET_SYSTICK();
99   do {
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();
103       if (size > 0) {
104         eth_mac->ReadFrame(in, size);
105         return ARM_DRIVER_OK;
106       }
107     }
108   }
109   while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT*1000));
110
111   return ARM_DRIVER_ERROR;
112 }
113
114 // Initialize MAC driver wrapper for RMII interface
115 static int32_t mac_initialize (ARM_ETH_MAC_SignalEvent_t cb_event) {
116   ARM_DRIVER_ETH_MAC *drv_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
117
118   phy_power = 1U;
119   return drv_mac->Initialize(cb_event);
120 }
121
122 // Uninitialize MAC driver wrapper for RMII interface
123 static int32_t mac_uninitialize (void) {
124   ARM_DRIVER_ETH_MAC *drv_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
125
126   phy_power = 0U;
127   return drv_mac->Uninitialize();
128 }
129
130 // MAC driver power control wrapper for RMII interface
131 static int32_t mac_power_control (ARM_POWER_STATE state) {
132   ARM_DRIVER_ETH_MAC *drv_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
133   ARM_DRIVER_ETH_PHY *drv_phy = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
134   int32_t retv;
135
136   retv = drv_mac->PowerControl(state);
137   if ((state == ARM_POWER_FULL) && (retv == ARM_DRIVER_ERROR) && (phy_power == 1U)) {
138     /* RMII solution when the PHY is a 50 MHz reference clock source   */
139     /* MAC never exits soft reset when PHY is powered down (no 50 MHz) */
140     /* So turn on the power for the PHY here to prevent deadlock       */
141     drv_phy->Initialize(drv_mac->PHY_Read, drv_mac->PHY_Write);
142     if (drv_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK) {
143       phy_power = 2U;
144       osDelay (10);
145       retv = drv_mac->PowerControl(state);
146       if (retv == ARM_DRIVER_OK) {
147         /* RMII lockup detected */
148         mac_lockup = 1U;
149       }
150     }
151   }
152   return (retv);
153 }
154
155 // PHY driver power control wrapper for RMII interface
156 static int32_t phy_power_control (ARM_POWER_STATE state) {
157   ARM_DRIVER_ETH_PHY *drv_phy = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
158   int32_t retv;
159
160   retv = drv_phy->PowerControl(state);
161   if ((state == ARM_POWER_OFF) && (retv == ARM_DRIVER_OK) && (phy_power == 2U)) {
162     phy_power = 1U;
163   }
164   return (retv);
165 }
166
167 /* Helper function that is called before tests start executing */
168 void ETH_DV_Initialize (void) {
169   static struct _ARM_DRIVER_ETH_MAC s_mac;
170   static struct _ARM_DRIVER_ETH_PHY s_phy;
171
172   eth_mac = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
173   eth_phy = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
174   capab   = eth_mac->GetCapabilities();
175   if (capab.media_interface == ARM_ETH_INTERFACE_RMII) {
176     memcpy(&s_mac, eth_mac, sizeof(s_mac));
177     memcpy(&s_phy, eth_phy, sizeof(s_phy));
178     /* Use wrapper functions in RMII interface mode */
179     s_mac.Initialize   = &mac_initialize;
180     s_mac.Uninitialize = &mac_uninitialize;
181     s_mac.PowerControl = &mac_power_control;
182     s_phy.PowerControl = &phy_power_control;
183     eth_mac = &s_mac;
184     eth_phy = &s_phy;
185     phy_power  = 0U;
186     mac_lockup = 0U;
187   }
188   cb_event = (capab.event_rx_frame) ? ETH_DrvEvent : NULL;
189 }
190
191 /* Helper function that is called after tests stop executing */
192 void ETH_DV_Uninitialize (void) {
193   eth_mac  = &CREATE_SYMBOL(Driver_ETH_MAC, DRV_ETH);
194   eth_phy  = &CREATE_SYMBOL(Driver_ETH_PHY, DRV_ETH);
195   cb_event = NULL;
196 }
197
198 /*-----------------------------------------------------------------------------
199  *      Tests
200  *----------------------------------------------------------------------------*/
201
202 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
203 /**
204 \defgroup dv_eth Ethernet Validation
205 \brief Ethernet driver validation
206 \details
207 The Ethernet validation test performs the following checks:
208 - API interface compliance.
209 - Data communication with various transfer sizes and communication parameters.
210 - Loopback communication.
211
212 \anchor eth_loopback
213 Loopback Communication Setup
214 ----------------------------
215
216 To perform loopback communication tests, it is required to connect the RX and TX lines of the Ethernet cable together:
217
218 - TX+ (Pin 1) with RX+ (Pin 3) and
219 - TX- (Pin 2) with RX- (Pin 6)
220
221 \image html ethernet_loopback.png
222
223 Various \b Ethernet \b loopback \b plugs are available from different vendors that fulfill this purpose.
224
225 \defgroup eth_tests Tests
226 \ingroup dv_eth
227
228 @{
229 */
230
231 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
232 /**
233 \brief Function: Function ETH_MAC_GetVersion
234 \details
235 The function \b ETH_MAC_GetVersion verifies the Ethernet MAC \b GetVersion function.
236 */
237 void ETH_MAC_GetVersion (void) {
238   ARM_DRIVER_VERSION ver;
239
240   ver = eth_mac->GetVersion();
241
242   TEST_ASSERT((ver.api >= ARM_DRIVER_VERSION_MAJOR_MINOR(1UL,0UL)) && (ver.drv >= ARM_DRIVER_VERSION_MAJOR_MINOR(1UL,0UL)));
243
244   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));
245   TEST_MESSAGE(str);
246 }
247
248 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
249 /**
250 \brief Function: ETH_MAC_GetCapabilities
251 \details
252 The function \b ETH_MAC_GetCapabilities verifies the Ethernet MAC \b GetCapabilities function.
253 */
254 void ETH_MAC_GetCapabilities (void) {
255   ARM_ETH_MAC_CAPABILITIES cap;
256
257   /* Get ETH_MAC capabilities */
258   cap = eth_mac->GetCapabilities();
259
260   TEST_ASSERT_MESSAGE((cap.reserved == 0U), "[FAILED] Capabilities reserved field must be 0");
261 }
262
263 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
264 /**
265 \brief Function: ETH_MAC_Initialization
266 \details
267 The function \b ETH_MAC_Initialization verifies the Ethernet MAC functions in the following order:
268   - \b Initialize without callback
269   - \b Uninitialize
270   - \b Initialize with callback if supported
271   - \b Uninitialize
272 */
273 void ETH_MAC_Initialization (void) {
274
275   /* Initialize without callback */
276   TEST_ASSERT(eth_mac->Initialize(NULL) == ARM_DRIVER_OK);
277
278   /* Uninitialize */
279   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
280
281   /* Initialize with callback if supported */
282   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
283
284   /* Uninitialize */
285   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
286 }
287
288 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
289 /**
290 \brief Function: ETH_MAC_CheckInvalidInit
291 \details
292 The function \b ETH_MAC_CheckInvalidInit verifies the driver behavior when receiving an invalid initialization sequence:
293   - \b Uninitialize
294   - \b PowerControl with Power off
295   - \b PowerControl with Power on
296   - \b Control
297   - \b PowerControl with Power off
298   - \b Uninitialize
299 */
300 void ETH_MAC_CheckInvalidInit (void) {
301
302   /* Uninitialize */
303   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
304
305   /* Power off */
306   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
307
308   /* Try to power on */
309   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) != ARM_DRIVER_OK);
310
311   /* Try to set configuration */
312   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
313     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL) != ARM_DRIVER_OK);
314
315   /* Power off */
316   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
317
318   /* Uninitialize */
319   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
320 }
321
322 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
323 /**
324 \brief Function: ETH_MAC_PowerControl
325 \details
326 The function \b ETH_MAC_PowerControl verifies the Ethernet MAC \b PowerControl function with the sequence:
327   - Initialize
328   - Power on
329   - Power low
330   - Power off
331   - Uninitialize
332 */
333 void ETH_MAC_PowerControl (void) {
334   int32_t retv;
335
336   /* Initialize with callback if supported */
337   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
338
339   /* Power on */
340   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
341
342   /* Power low */
343   retv = eth_mac->PowerControl(ARM_POWER_LOW);
344   if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
345   else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
346
347   /* Power off */
348   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
349
350   /* Uninitialize */
351   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
352 }
353
354 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
355 /**
356 \brief Function: ETH_MAC_MacAddress
357 \details
358 The function \b ETH_MAC_MacAddress verifies the Ethernet MAC \b GetMacAddress and \b SetMacAddress functions
359 with the sequence:
360   - Initialize
361   - Power on
362   - Set Ethernet MAC Address
363   - Get Ethernet MAC Address
364   - Power off
365   - Uninitialize
366 */
367 void ETH_MAC_MacAddress (void) {
368   ARM_ETH_MAC_ADDR my_addr;
369
370   /* Initialize with callback if supported and power on */
371   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
372   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
373
374   /* Set MAC Address */
375   TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
376
377   /* Verify MAC Address */
378   memset(&my_addr, 0, 6);
379   TEST_ASSERT(eth_mac->GetMacAddress(&my_addr) == ARM_DRIVER_OK);
380   if (memcmp(&mac_addr, &my_addr, 6) != 0) {
381     TEST_FAIL_MESSAGE("[FAILED] Verify MAC address");
382   } else TEST_PASS();
383
384   /* Power off */
385   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
386
387   /* Uninitialize */
388   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
389 }
390
391 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
392 /**
393 \brief Function: ETH_MAC_SetBusSpeed
394 \details
395 The function \b ETH_MAC_SetBusSpeed verifies the Ethernet MAC \b Control function with the sequence:
396   - Initialize
397   - Power on
398   - Set bus speed \token{10M}
399   - Set bus speed \token{100M}
400   - Set bus speed \token{1G}
401   - Power off
402   - Uninitialize
403 */
404 void ETH_MAC_SetBusSpeed (void) {
405   int32_t retv;
406
407   /* Initialize with callback if supported and power on */
408   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
409   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
410
411   /* Set bus speed 10M */
412   retv = eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_10M);
413   if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 10M is not supported"); }
414   else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
415
416   /* Set bus speed 100M */
417   retv = eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M);
418   if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 100M is not supported"); }
419   else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
420
421   /* Set bus speed 1G */
422   retv = eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_1G);
423   if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Link speed 1G is not supported"); }
424   else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
425
426   /* Power off and uninitialize */
427   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
428   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
429 }
430
431 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
432 /**
433 \brief Function: ETH_MAC_Config_Mode
434 \details
435 The function \b ETH_MAC_Config_Mode verifies the Ethernet MAC \b Control function with the sequence:
436   - Initialize
437   - Power on
438   - Set full duplex
439   - Set half duplex
440   - Power off
441   - Uninitialize
442 */
443 void ETH_MAC_Config_Mode (void) {
444
445   /* Initialize with callback if supported and power on */
446   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
447   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
448
449   /* Set full duplex */
450   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_FULL) == ARM_DRIVER_OK);
451
452   /* Set half duplex */
453   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_DUPLEX_HALF) == ARM_DRIVER_OK);
454
455   /* Power off and uninitialize */
456   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
457   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
458 }
459
460 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
461 /**
462 \brief Function: ETH_MAC_Config_CommonParams
463 \details
464 The function \b ETH_MAC_Config_CommonParams verifies the Ethernet MAC \b Control function with the sequence:
465   - Initialize
466   - Power on
467   - Configure Ethernet MAC bus
468   - Configure receiver
469   - Configure transmitter
470   - Power off
471   - Uninitialize
472 */
473 void ETH_MAC_Config_CommonParams (void) {
474
475   /* Initialize with callback if supported and power on */
476   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
477   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
478
479   /* Configure ETH_MAC bus*/
480   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
481     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
482
483   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
484
485   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
486
487   /* Power off and uninitialize */
488   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
489   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
490 }
491
492 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
493 /**
494 \brief  Function: ETH_MAC_Control_Filtering
495 \details
496 The function \b ETH_MAC_Control_Filtering verifies the Ethernet MAC \b Control function with the following sequence:
497   - Buffer allocation
498   - Initialize
499   - Power on
500   - Broadcast receive
501   - Receive with broadcast disabled
502   - Multicast receive
503   - Receive with multicast disabled
504   - Unicast receive
505   - Promiscuous mode receive
506   - Power off
507   - Uninitialize
508
509 \note
510 The internal Ethernet MAC loopback is used for the test.
511 */
512 void ETH_MAC_Control_Filtering (void) {
513   uint32_t i,tick;
514
515   /* Allocate buffers */
516   buffer_out = (uint8_t *)malloc(64);
517   TEST_ASSERT(buffer_out != NULL);
518   if (buffer_out == NULL) return;
519   buffer_in = (uint8_t *)malloc(64);
520   TEST_ASSERT(buffer_in != NULL);
521   if (buffer_in == NULL) { free(buffer_out); return; }
522
523   /* Initialize, power on and configure MAC and PHY */
524   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
525   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
526   TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
527   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M |
528     ARM_ETH_MAC_DUPLEX_FULL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
529   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
530   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
531   osDelay (100);
532   TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
533   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
534   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
535   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
536
537   /* Set Ethernet header */
538   memcpy(&buffer_out[6], &mac_addr, 6);
539   buffer_out[12] = 0;
540   buffer_out[13] = 50;
541
542   for (i = 14; i < 64; i++) {
543     buffer_out[i] = i + 'A' - 14;
544   }
545
546   /* Broadcast receive */
547   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK |
548     ARM_ETH_MAC_ADDRESS_BROADCAST) == ARM_DRIVER_OK);
549   memcpy(&buffer_out[0], &mac_bcast, 6);
550   if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
551     TEST_FAIL_MESSAGE("[FAILED] Receive broadcast");
552   } else TEST_PASS();
553
554   /* Receive with broadcast disabled */
555   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
556   if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
557     TEST_MESSAGE("[WARNING] Broadcast receive not disabled");
558   }
559
560   /* Multicast receive */
561   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK |
562     ARM_ETH_MAC_ADDRESS_MULTICAST) == ARM_DRIVER_OK);
563   for (i = 0; i < 6; i++) {
564     memcpy(&buffer_out[0], &mac_mcast[i], 6);
565     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
566       snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
567       TEST_FAIL_MESSAGE(str);
568     } else TEST_PASS();
569   }
570
571   /* Receive with multicast disabled */
572   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
573   memcpy(&buffer_out[0], &mac_mcast[0], 6);
574   if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
575     TEST_MESSAGE("[WARNING] Multicast receive not disabled");
576   }
577
578   /* Unicast receive */
579   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
580   memcpy(&buffer_out[0], &mac_addr, 6);
581   if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
582     TEST_FAIL_MESSAGE("[FAILED] Receive unicast");
583   } else TEST_PASS();
584
585   /* Promiscuous mode receive */
586   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_LOOPBACK |
587     ARM_ETH_MAC_ADDRESS_ALL) == ARM_DRIVER_OK);
588   /* Test broadcast receive */
589   memcpy(&buffer_out[0], &mac_bcast, 6);
590   if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
591     TEST_FAIL_MESSAGE("[FAILED] Receive broadcast in promiscuous mode");
592   } else TEST_PASS();
593   /* Test multicast receive */
594   memcpy(&buffer_out[0], &mac_mcast[0], 6);
595   if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
596     TEST_FAIL_MESSAGE("[FAILED] Receive multicast in promiscuous mode");
597   } else TEST_PASS();
598   /* Test unicast receive */
599   memcpy(&buffer_out[0], &mac_addr, 6);
600   if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
601     TEST_FAIL_MESSAGE("[FAILED] Receive unicast in promiscuous mode");
602   } else TEST_PASS();
603
604   /* Power off and uninitialize */
605   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
606   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
607   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
608   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
609
610   /* Free buffers */
611   free(buffer_out);
612   free(buffer_in);
613 }
614
615 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
616 /**
617 \brief  Function: ETH_MAC_SetAddressFilter
618 \details
619 The function \b ETH_MAC_SetAddressFilter verifies the Ethernet MAC \b SetAddressFilter function with the following sequence:
620   - Buffer allocation
621   - Initialize
622   - Power on
623   - Receive one multicast address
624   - Receive two multicast addresses
625   - Receive three multicast addresses
626   - Receive four multicast addresses
627   - Receive six multicast addresses
628   - Power off
629   - Uninitialize
630
631 \note
632 The internal Ethernet MAC loopback is used for the test.
633 */
634 void ETH_MAC_SetAddressFilter (void) {
635   uint32_t i,tick;
636
637   /* Allocate buffers */
638   buffer_out = (uint8_t *)malloc(64);
639   TEST_ASSERT(buffer_out != NULL);
640   if (buffer_out == NULL) return;
641   buffer_in = (uint8_t *)malloc(64);
642   TEST_ASSERT(buffer_in != NULL);
643   if (buffer_in == NULL) { free(buffer_out); return; }
644
645   /* Initialize, power on and configure MAC and PHY */
646   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
647   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
648   TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
649   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M |
650     ARM_ETH_MAC_DUPLEX_FULL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
651   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
652   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
653   osDelay (100);
654   TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
655   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
656   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
657   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
658
659   /* Set Ethernet header */
660   memcpy(&buffer_out[6], &mac_addr, 6);
661   buffer_out[12] = 0;
662   buffer_out[13] = 50;
663
664   for (i = 14; i < 64; i++) {
665     buffer_out[i] = i + 'A' - 14;
666   }
667
668   /* Receive one multicast address */
669   TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 1) == ARM_DRIVER_OK);
670
671   memcpy(&buffer_out[0], &mac_mcast[0], 6);
672   if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
673     /* Error, enabled multicast address not received */
674     TEST_FAIL_MESSAGE("[FAILED] Receive multicast 0 address");
675   } else TEST_PASS();
676
677   for (i = 1; i < 6; i++) {
678     memcpy(&buffer_out[0], &mac_mcast[i], 6);
679     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
680       /* Warning, disabled multicast address received */
681       snprintf(str,sizeof(str),"[WARNING] Receive multicast %d address",i);
682       TEST_MESSAGE(str);
683     }
684   }
685
686   /* Receive two multicast addresses */
687   TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 2) == ARM_DRIVER_OK);
688
689   for (i = 0; i < 2; i++) {
690     memcpy(&buffer_out[0], &mac_mcast[i], 6);
691     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
692       /* Error, enabled multicast address not received */
693       snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
694       TEST_FAIL_MESSAGE(str);
695     } else TEST_PASS();
696   }
697
698   for (; i < 6; i++) {
699     memcpy(&buffer_out[0], &mac_mcast[i], 6);
700     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
701       /* Warning, disabled multicast address received */
702       snprintf(str,sizeof(str),"[WARNING] Receive multicast %d address",i);
703       TEST_MESSAGE(str);
704     }
705   }
706
707   /* Receive three multicast addresses */
708   TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 3) == ARM_DRIVER_OK);
709
710   for (i = 0; i < 3; i++) {
711     memcpy(&buffer_out[0], &mac_mcast[i], 6);
712     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
713       /* Error, enabled multicast address not received */
714       snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
715       TEST_FAIL_MESSAGE(str);
716     } else TEST_PASS();
717   }
718
719   for (; i < 6; i++) {
720     memcpy(&buffer_out[0], &mac_mcast[i], 6);
721     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
722       /* Warning, disabled multicast address received */
723       snprintf(str,sizeof(str),"[WARNING] Receive multicast %d address",i);
724       TEST_MESSAGE(str);
725     }
726   }
727
728   /* Receive four multicast addresses */
729   TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 4) == ARM_DRIVER_OK);
730
731   for (i = 0; i < 4; i++) {
732     memcpy(&buffer_out[0], &mac_mcast[i], 6);
733     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
734       /* Error, enabled multicast address not received */
735       snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
736       TEST_FAIL_MESSAGE(str);
737     } else TEST_PASS();
738   }
739
740   for (; i < 6; i++) {
741     memcpy(&buffer_out[0], &mac_mcast[i], 6);
742     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) == ARM_DRIVER_OK) {
743       /* Warning, disabled multicast address received */
744       snprintf(str,sizeof(str),"[WARNING] Receive multicast %d address",i);
745       TEST_MESSAGE(str);
746     }
747   }
748
749   /* Receive all multicast addresses */
750   TEST_ASSERT(eth_mac->SetAddressFilter(mac_mcast, 6) == ARM_DRIVER_OK);
751
752   for (i = 0; i < 6; i++) {
753     memcpy(&buffer_out[0], &mac_mcast[i], 6);
754     if (ETH_RunTransfer(buffer_out, buffer_in, 64, 0) != ARM_DRIVER_OK) {
755       /* Error, enabled multicast address not received */
756       snprintf(str,sizeof(str),"[FAILED] Receive multicast %d address",i);
757       TEST_FAIL_MESSAGE(str);
758     } else TEST_PASS();
759   }
760
761   /* Power off and uninitialize */
762   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
763   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
764   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
765   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
766
767   /* Free buffers */
768   free(buffer_out);
769   free(buffer_in);
770 }
771
772 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
773 /**
774 \brief Function: ETH_MAC_SignalEvent
775 \details
776 The function \b ETH_MAC_SignalEvent verifies the Ethernet MAC interrupt operation with the sequence:
777   - Initialize
778   - Power on
779   - Configure receiver
780   - Configure transmitter
781   - Set output buffer pattern
782   - Send data and check receive interrupts
783   - Power off
784   - Uninitialize
785
786 \note
787 The internal Ethernet MAC loopback is used for the test.
788 */
789 void ETH_MAC_SignalEvent (void) {
790   uint32_t i,tick;
791
792   if (!capab.event_rx_frame) {
793     TEST_MESSAGE("[WARNING] Interrupt mode is not supported");
794     return;
795   }
796
797   /* Allocate buffer */
798   buffer_out = (uint8_t *)malloc(64);
799   TEST_ASSERT(buffer_out != NULL);
800   if (buffer_out == NULL) return;
801
802   /* Initialize, power on and configure MAC */
803   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
804   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
805   TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
806   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
807     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
808   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
809   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
810   osDelay (100);
811   TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
812   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
813   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
814   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
815
816   /* Set Ethernet header */
817   memcpy(&buffer_out[0], &mac_bcast, 6);
818   memcpy(&buffer_out[6], &mac_addr,  6);
819   buffer_out[12] = 0;
820   buffer_out[13] = 50;
821
822   for (i = 14; i < 64; i++) {
823     buffer_out[i] = i + 'A' - 14;
824   }
825
826   Event &= ~ARM_ETH_MAC_EVENT_RX_FRAME;
827   TEST_ASSERT(eth_mac->SendFrame(buffer_out, 64, 0) == ARM_DRIVER_OK);
828
829   /* Wait for RX interrupt event */
830   tick = GET_SYSTICK();
831   do {
832     if (Event & ARM_ETH_MAC_EVENT_RX_FRAME) {
833       break;
834     }
835   }
836   while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT*1000));
837
838   if (!(Event & ARM_ETH_MAC_EVENT_RX_FRAME)) {
839     TEST_FAIL_MESSAGE("[FAILED] Interrupt mode not working");
840   } else TEST_PASS();
841
842   /* Power off and uninitialize */
843   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
844   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
845   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
846   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
847 }
848
849 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
850 /**
851 \brief Function: Function ETH_PHY_GetVersion
852 \details
853 The function \b ETH_PHY_GetVersion verifies the Ethernet PHY \b GetVersion function.
854 */
855 void ETH_PHY_GetVersion (void) {
856   ARM_DRIVER_VERSION ver;
857
858   ver = eth_phy->GetVersion();
859
860   TEST_ASSERT((ver.api >= ARM_DRIVER_VERSION_MAJOR_MINOR(1UL,0UL)) && (ver.drv >= ARM_DRIVER_VERSION_MAJOR_MINOR(1UL,0UL)));
861
862   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));
863   TEST_MESSAGE(str);
864 }
865
866 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
867 /**
868 \brief Function: ETH_PHY_Initialization
869 \details
870 The function \b ETH_PHY_Initialization verifies the Ethernet PHY functions in the following order:
871   - \b Initialize with read and write functions
872 */
873 void ETH_PHY_Initialization (void) {
874
875   /* MAC Initialize and power on */
876   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
877   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
878
879   /* Initialize */
880   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
881
882   /* Uninitialize */
883   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
884
885   /* MAC Power off and uninitialize */
886   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
887   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
888 }
889
890 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
891 /**
892 \brief Function: ETH_PHY_CheckInvalidInit
893 \details
894 The function \b ETH_PHY_CheckInvalidInit verifies the driver behavior when receiving an invalid initialization sequence:
895   - \b Uninitialize
896   - \b PowerControl with Power off
897   - \b PowerControl with Power on
898   - \b SetInterface to configure the Ethernet PHY bus
899   - \b SetMode to configure the Ethernet PHY bus
900   - \b PowerControl with Power off
901   - \b Uninitialize
902 */
903 void ETH_PHY_CheckInvalidInit (void) {
904
905   /* Uninitialize */
906   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
907
908   /* Power off */
909   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) != ARM_DRIVER_OK);
910
911   /* Try to power on */
912   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) != ARM_DRIVER_OK);
913
914   /* Try to configure ETH_PHY bus*/
915   TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) != ARM_DRIVER_OK);
916   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) != ARM_DRIVER_OK);
917
918   /* Try to initialize without read and write functions */
919   TEST_ASSERT(eth_phy->Initialize(NULL, NULL) != ARM_DRIVER_OK);
920
921   /* Power off */
922   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) != ARM_DRIVER_OK);
923
924   /* Uninitialize */
925   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
926 }
927
928 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
929 /**
930 \brief Function: ETH_PHY_PowerControl
931 \details
932 The function \b ETH_PHY_PowerControl verifies the Ethernet PHY \b PowerControl function with the sequence:
933   - Initialize
934   - Power on
935   - Power low
936   - Power off
937   - Check RMII lockup
938   - Uninitialize
939
940 \note
941 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
942 and therefore not generating a reference clock.
943 */
944 void ETH_PHY_PowerControl (void) {
945   int32_t retv;
946
947   /* MAC Initialize and power on */
948   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
949   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
950
951   /* Initialize */
952   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
953
954   /* Power on */
955   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
956
957   /* Power low */
958   retv = eth_phy->PowerControl(ARM_POWER_LOW);
959   if (retv == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
960   else { TEST_ASSERT(retv == ARM_DRIVER_OK); }
961
962   /* Power off */
963   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
964
965   /* Uninitialize */
966   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
967
968   /* Check RMII lockup */
969   if ((capab.media_interface == ARM_ETH_INTERFACE_RMII) && (!mac_lockup)) {
970     eth_mac->PowerControl(ARM_POWER_OFF);
971     eth_mac->PowerControl(ARM_POWER_FULL);
972     eth_phy->PowerControl(ARM_POWER_OFF);
973     eth_phy->Uninitialize();
974   }
975   if (mac_lockup) {
976     TEST_MESSAGE("[WARNING] MAC is locked when PHY power is off");
977   }
978
979   /* MAC Power off and uninitialize */
980   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
981   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
982 }
983
984 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
985 /**
986 \brief  Function: ETH_PHY_Config
987 \details
988 The function \b ETH_PHY_Config verifies the PHY functions
989   - Initialize
990   - Power on
991   - SetInterface
992   - SetMode
993   - Power off
994   - Uninitialize
995 */
996 void ETH_PHY_Config (void) {
997
998   /* MAC Initialize and power on */
999   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1000   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1001
1002   /* Initialize and power on */
1003   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1004   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1005
1006   /* Configure ETH_PHY bus */
1007   TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
1008
1009   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
1010
1011   /* Power off and uninitialize */
1012   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1013   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1014
1015   /* MAC Power off and uninitialize */
1016   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1017   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1018 }
1019
1020 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1021 /**
1022 \brief  Function: ETH_Loopback_Transfer
1023 \details
1024 The function \b ETH_Loopback_Transfer verifies data transfer via Ethernet with the following sequence:
1025   - Buffer allocation
1026   - Initialize
1027   - Power on
1028   - Set output buffer pattern
1029   - Transfer data chunks
1030   - Set output buffer with random data
1031   - Transfer data chunks
1032   - Transfer data by sending in two fragments
1033   - Power off
1034   - Uninitialize
1035
1036 \note
1037 The internal Ethernet MAC loopback is used as a data loopback, so there is no need to use an external loopback cable.
1038 */
1039 void ETH_Loopback_Transfer (void) {
1040   const uint16_t test_len[] = {
1041     28,36,40,44,45,46,47,48,49,50,55,60,65,70,75,80,85,90,95,100,110,120,127,128,
1042     129,140,150,160,170,180,190,196,200,220,240,250,256,270,300,325,350,375,400,
1043     425,450,475,500,511,512,513,525,550,575,600,625,650,700,750,800,850,900,950,
1044     1000,1024,1050,1100,1150,1200,1250,1300,1320,1420,1480,1490,1491,1492,1493,
1045     1494,1495,1496,1497,1498,1499,1500};
1046   const uint32_t test_num = ARRAY_SIZE(test_len);
1047   uint32_t i,cnt,tick;
1048
1049   /* Allocate buffers, add space for Ethernet header */
1050   buffer_out = (uint8_t *)malloc(14+ETH_MTU);
1051   TEST_ASSERT(buffer_out != NULL);
1052   if (buffer_out == NULL) return;
1053   buffer_in = (uint8_t *)malloc(14+ETH_MTU);
1054   TEST_ASSERT(buffer_in != NULL);
1055   if (buffer_in == NULL) { free(buffer_out); return; }
1056
1057   /* Initialize, power on and configure MAC */
1058   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1059   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1060   TEST_ASSERT(eth_mac->SetMacAddress(&mac_addr) == ARM_DRIVER_OK);
1061   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
1062     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
1063   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1064   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1065   osDelay (100);
1066   TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
1067   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
1068   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
1069   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
1070
1071   /* Set output buffer pattern */
1072   for (i = 0; i < ETH_MTU; i+=2) {
1073     buffer_out[14+i] = 0x55;
1074     buffer_out[15+i] = 0xAA;
1075   }
1076
1077   /* Set Ethernet header */
1078   memcpy(&buffer_out[0], &mac_bcast, 6);
1079   memcpy(&buffer_out[6], &mac_addr,  6);
1080
1081   /* Transfer data chunks */
1082   for (cnt = 0; cnt < test_num; cnt++) {
1083     /* Clear input buffer */
1084     memset(buffer_in, 0, test_len[cnt]);
1085     /* Set Ethernet type/length */
1086     buffer_out[12] = test_len[cnt] >> 8;
1087     buffer_out[13] = test_len[cnt] & 0xFF;
1088     if (ETH_RunTransfer(buffer_out, buffer_in, 14+test_len[cnt], 0) != ARM_DRIVER_OK) {
1089       snprintf(str,sizeof(str),"[FAILED] Transfer block of %d bytes",test_len[cnt]);
1090       TEST_FAIL_MESSAGE(str);
1091     } else if (memcmp(buffer_in, buffer_out, 14+test_len[cnt]) != 0) {
1092       snprintf(str,sizeof(str),"[FAILED] Verify block of %d bytes",test_len[cnt]);
1093       TEST_FAIL_MESSAGE(str);
1094     } else TEST_PASS();
1095   }
1096
1097   /* Set output buffer with random data */
1098   srand(GET_SYSTICK());
1099   for (i = 0; i < ETH_MTU; i++) {
1100     buffer_out[14+cnt] = (uint8_t)rand();
1101   }
1102
1103   /* Transfer data chunks */
1104   for (cnt = 0; cnt < test_num; cnt++) {
1105     /* Clear input buffer */
1106     memset(buffer_in, 0, test_len[cnt]);
1107     /* Set Ethernet type/length */
1108     buffer_out[12] = test_len[cnt] >> 8;
1109     buffer_out[13] = test_len[cnt] & 0xFF;
1110     if (ETH_RunTransfer(buffer_out, buffer_in, 14+test_len[cnt], 0) != ARM_DRIVER_OK) {
1111       snprintf(str,sizeof(str),"[FAILED] Transfer block of %d bytes",test_len[cnt]);
1112       TEST_FAIL_MESSAGE(str);
1113     } else if (memcmp(buffer_in, buffer_out, 14+test_len[cnt]) != 0) {
1114       snprintf(str,sizeof(str),"[FAILED] Verify block of %d bytes",test_len[cnt]);
1115       TEST_FAIL_MESSAGE(str);
1116     } else TEST_PASS();
1117   }
1118
1119   /* Block transfer in two fragments: header and data */
1120   for (cnt = 0; cnt < test_num; cnt++) {
1121     /* Clear input buffer */
1122     memset(buffer_in, 0, test_len[cnt]);
1123     /* Set Ethernet type/length */
1124     buffer_out[12] = test_len[cnt] >> 8;
1125     buffer_out[13] = test_len[cnt] & 0xFF;
1126     if (ETH_RunTransfer(buffer_out, buffer_in, 14+test_len[cnt], 0) != ARM_DRIVER_OK) {
1127       snprintf(str,sizeof(str),"[FAILED] Fragmented block transfer of %d bytes",test_len[cnt]);
1128       TEST_FAIL_MESSAGE(str);
1129     } else if (memcmp(buffer_in, buffer_out, 14+test_len[cnt]) != 0) {
1130       snprintf(str,sizeof(str),"[FAILED] Fragmented block check of %d bytes",test_len[cnt]);
1131       TEST_FAIL_MESSAGE(str);
1132     } else TEST_PASS();
1133   }
1134
1135   /* Power off and uninitialize */
1136   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1137   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1138   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1139   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1140
1141   /* Free buffers */
1142   free(buffer_out);
1143   free(buffer_in);
1144 }
1145
1146 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1147 /**
1148 \brief  Function: ETH_Loopback_External
1149 \details
1150 The function \b ETH_Loopback_External verifies data transfer via Ethernet with the following sequence:
1151   - Buffer allocation
1152   - Initialize
1153   - Power on
1154   - Set output buffer pattern
1155   - Transfer data on PHY internal loopback
1156   - Ethernet connection
1157   - Transfer data on external cable loopback
1158   - Power off
1159   - Uninitialize
1160
1161 \note
1162 An external loopback cable is required for this test.
1163 */
1164 void ETH_Loopback_External (void) {
1165   ARM_ETH_LINK_INFO info;
1166   uint32_t i,cnt,tick;
1167
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; }
1175
1176   /* Initialize, power on and configure MAC and PHY */
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_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);
1184   osDelay (100);
1185   TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
1186   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_SPEED_100M |
1187    ARM_ETH_PHY_DUPLEX_FULL | ARM_ETH_PHY_LOOPBACK) == ARM_DRIVER_OK);
1188   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
1189   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
1190
1191   /* Fill output buffer */
1192   for (cnt = 0; cnt < ETH_MTU; cnt++) {
1193     buffer_out[14+cnt] = (cnt ^ 0x20) & 0x7F;
1194   }
1195
1196   /* Set Ethernet header */
1197   memcpy(&buffer_out[0], &mac_bcast, 6);
1198   memcpy(&buffer_out[6], &mac_addr,  6);
1199
1200   /* Set Ethernet type/length */
1201   buffer_out[12] = (ETH_MTU >> 8) & 0xFF;
1202   buffer_out[13] =  ETH_MTU       & 0xFF;
1203
1204   /* Check PHY internal loopback */
1205   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_SPEED_100M |
1206     ARM_ETH_PHY_DUPLEX_FULL | ARM_ETH_PHY_LOOPBACK) == ARM_DRIVER_OK);
1207   osDelay(200);
1208
1209   /* Clear input buffer*/
1210   memset(buffer_in, 0, 14+ETH_MTU);
1211   if (ETH_RunTransfer(buffer_out, buffer_in, 14+ETH_MTU, 0) != ARM_DRIVER_OK) {
1212     TEST_MESSAGE("[WARNING] PHY internal loopback is not active");
1213   } else if (memcmp(buffer_in, buffer_out, 14+ETH_MTU) != 0) {
1214     TEST_FAIL_MESSAGE("[FAILED] Verify received data");
1215   } else TEST_PASS();
1216
1217   /* Check external cable loopback */
1218   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
1219
1220   /* Check Ethernet link */
1221   tick = GET_SYSTICK();
1222   while (eth_phy->GetLinkState() != ARM_ETH_LINK_UP) {
1223     if ((GET_SYSTICK() - tick) >= SYSTICK_MICROSEC(ETH_LINK_TIMEOUT*1000)) {
1224       TEST_FAIL_MESSAGE("[FAILED] Link down, connect Ethernet cable");
1225       goto end;
1226     }
1227   }
1228
1229   info = eth_phy->GetLinkInfo();
1230   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE,
1231     (uint32_t)info.speed  << ARM_ETH_MAC_SPEED_Pos  |
1232     (uint32_t)info.duplex << ARM_ETH_MAC_DUPLEX_Pos |
1233     ARM_ETH_MAC_ADDRESS_BROADCAST) == ARM_DRIVER_OK);
1234
1235   /* Clear input buffer*/
1236   memset(buffer_in, 0, 14+ETH_MTU);
1237   if (ETH_RunTransfer(buffer_out, buffer_in, 14+ETH_MTU, 0) != ARM_DRIVER_OK) {
1238     TEST_FAIL_MESSAGE("[FAILED] Transfer external cable loopback");
1239   } else if (memcmp(buffer_in, buffer_out, 14+ETH_MTU) != 0) {
1240     TEST_FAIL_MESSAGE("[FAILED] Verify received data");
1241   } else TEST_PASS();
1242
1243   /* Power off and uninitialize */
1244   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1245   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1246   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1247   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1248 end:
1249   /* Free buffers */
1250   free(buffer_out);
1251   free(buffer_in);
1252 }
1253
1254 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1255 /**
1256 \brief Function: ETH_MAC_PTP_ControlTimer
1257 \details
1258 The function \b ETH_MAC_PTP_ControlTimer verifies the PTP \b ControlTimer function with the sequence:
1259   - Initialize
1260   - Power on
1261   - Set Time
1262   - Adjust Clock
1263   - Increment Time
1264   - Decrement Time
1265   - Set Alarm
1266   - Power off
1267   - Uninitialize
1268 */
1269 void ETH_MAC_PTP_ControlTimer (void) {
1270   ARM_ETH_MAC_TIME time1,time2;
1271   int64_t t,t1ns,t2ns,overhead;
1272   double rate;
1273
1274   /* Get capabilities */
1275   if (!capab.precision_timer) {
1276     TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
1277     return;
1278   }
1279
1280   /* Initialize, power on and configure MAC */
1281   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1282   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1283
1284   /* Set Time -------------------------------------------------------------------------------- */
1285   time1.sec = 0U;
1286   time1.ns  = 0U;
1287   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
1288
1289   /* Check System Time */
1290   osDelay(1U);
1291   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1292   osDelay(PTP_TIME_REF);
1293   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1294
1295   /* Get timestamps in nanoseconds */
1296   t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1297   t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1298   t    = t2ns - t1ns - PTP_TIME_REF_NS;
1299
1300   /* Check timestamps difference */
1301   if (llabs(t) > ETH_PTP_TOLERANCE) {
1302     snprintf(str,sizeof(str),"[WARNING] PTP measured time is %lldns from expected", t);
1303     TEST_MESSAGE(str);
1304   } else TEST_PASS();
1305
1306   /* Adjust clock - Set correction factor ---------------------------------------------------- */
1307   /* Calculate rate and convert it to q31 format */
1308   rate     = (double)PTP_TIME_REF_NS / (t2ns-t1ns);
1309   time1.ns = (uint32_t)(0x80000000U*rate);
1310   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_ADJUST_CLOCK, &time1) == ARM_DRIVER_OK);
1311
1312   /* Check System Time after adjusting clock */
1313   osDelay(1U);
1314   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1315   osDelay(PTP_TIME_REF);
1316   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1317
1318   /* Get timestamps in nanoseconds */
1319   t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1320   t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1321   t    = t2ns - t1ns - PTP_TIME_REF_NS;
1322
1323   /* Check timestamps difference */
1324   if (llabs(t) > ETH_PTP_TOLERANCE) {
1325     snprintf(str,sizeof(str),"[WARNING] PTP measured time with adj clk is %lldns from expected", t);
1326     TEST_MESSAGE(str);
1327   } else TEST_PASS();
1328
1329   /* Measure time overhead for increment/decrement calls ------------------------------------- */
1330   time2.sec = 0;
1331   time2.ns  = 0;
1332   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1333   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_INC_TIME, &time2) == ARM_DRIVER_OK);
1334   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1335   t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1336   t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1337   overhead = t2ns - t1ns;
1338
1339   /* Increment time -------------------------------------------------------------------------- */
1340   time2.sec = PTP_TIME_REF/1000U;
1341   time2.ns  = (PTP_TIME_REF-time2.sec*1000U)*1000000U;
1342   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1343   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_INC_TIME, &time2) == ARM_DRIVER_OK);
1344   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1345
1346   /* Get timestamps in nanoseconds */
1347   t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1348   t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1349   t    = t2ns - t1ns - PTP_TIME_REF_NS - overhead;
1350
1351   /* Check timestamps difference */
1352   if (llabs(t) > ETH_PTP_TOLERANCE) {
1353     snprintf(str,sizeof(str),"[WARNING] PTP incremented time is %lldns from expected", t);
1354     TEST_MESSAGE(str);
1355   } else TEST_PASS();
1356
1357   /* Decrement time -------------------------------------------------------------------------- */
1358   time2.sec =  PTP_TIME_REF/1000U;
1359   time2.ns  = (PTP_TIME_REF-time2.sec*1000U)*1000000U;
1360   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1361   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_DEC_TIME, &time2) == ARM_DRIVER_OK);
1362   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1363
1364   /* Get timestamps in nanoseconds */
1365   t1ns = (int64_t)time1.sec*PTP_S_NS + time1.ns;
1366   t2ns = (int64_t)time2.sec*PTP_S_NS + time2.ns;
1367   t    = t2ns - t1ns + PTP_TIME_REF_NS - overhead;
1368
1369   /* Check timestamps difference */
1370   if (llabs(t) > ETH_PTP_TOLERANCE) {
1371     snprintf(str,sizeof(str),"[WARNING] PTP decremented time is %lldns from expected", t);
1372     TEST_MESSAGE(str);
1373   } else TEST_PASS();
1374
1375   /* Set Alarm (1s) -------------------------------------------------------------------------- */
1376   Event &= ~ARM_ETH_MAC_EVENT_TIMER_ALARM;
1377   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1378   time1.sec += 1U;
1379   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_ALARM, &time1) == ARM_DRIVER_OK);
1380
1381   /* Check alarm event after 999ms */
1382   osDelay(999U);
1383   if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) != 0)  {
1384     TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event triggered too early");
1385   } else TEST_PASS();
1386
1387   /* Check alarm event after 1001ms */
1388   osDelay(2U);
1389   if ((Event & ARM_ETH_MAC_EVENT_TIMER_ALARM) == 0)  {
1390     TEST_FAIL_MESSAGE("[FAILED] PTP Alarm event timeout");
1391   } else TEST_PASS();
1392
1393   /* Power off and uninitialize */
1394   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1395   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1396 }
1397
1398 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1399 /**
1400 \brief Function: ETH_Loopback_PTP
1401 \details
1402 The function \b ETH_Loopback_PTP verifies the Precision Time Protocol functions \b ControlTimer, \b GetRxFrameTime and
1403 \b GetTxFrameTime with the sequence:
1404   - Initialize
1405   - Power on
1406   - Set Control Timer
1407   - Transfer a frame
1408   - Get TX frame time
1409   - Get RX frame time
1410   - Power off
1411   - Uninitialize
1412
1413 \note
1414 The internal Ethernet MAC loopback is used as the data loopback.
1415 */
1416 void ETH_Loopback_PTP (void) {
1417   ARM_ETH_MAC_TIME time1,time2;
1418   uint32_t tick;
1419
1420   // PTP over Ethernet IPv4 sample frame
1421   const uint8_t PTP_frame[] = {
1422     0x01,0x00,0x5e,0x00,0x01,0x81,0x02,0x30,0x05,0x1d,0x1e,0x27,0x08,0x00,0x45,0x00,
1423     0x00,0x98,0x00,0x5d,0x40,0x00,0x01,0x11,0x29,0x68,0x0a,0x0a,0x64,0x05,0xe0,0x00,
1424     0x01,0x81,0x01,0x3f,0x01,0x3f,0x00,0x84,0xc0,0x7b,0x00,0x01,0x00,0x01,0x5f,0x44,
1425     0x46,0x4c,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
1426     0x00,0x30,0x05,0x1d,0x1e,0x27,0x00,0x01,0x00,0x5e,0x00,0x00,0x00,0x08,0x00,0x00,
1427     0x00,0x00,0x45,0x5b,0x0a,0x38,0x0e,0xb9,0x26,0x58,0x00,0x00,0x00,0x00,0x00,0x01,
1428     0x00,0x30,0x05,0x1d,0x1e,0x27,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x04,0x44,0x46,
1429     0x4c,0x54,0x00,0x00,0xf0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
1430     0xf0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x44,0x46,0x4c,0x54,0x00,0x01,
1431     0x00,0x30,0x05,0x1d,0x1e,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1432     0x00,0x00,0x00,0x00,0x00,0x00
1433   };
1434   const uint32_t PTP_frame_len = sizeof(PTP_frame);
1435
1436   /* Get capabilities */
1437   if (!capab.precision_timer) {
1438     TEST_MESSAGE("[WARNING] Precision Time Protocol is not supported");
1439     return;
1440   }
1441
1442   /* Allocate buffer */
1443   buffer_in = (uint8_t *)malloc(PTP_frame_len);
1444   TEST_ASSERT(buffer_in != NULL);
1445   if (buffer_in == NULL) return;
1446
1447   /* Initialize, power on and configure MAC and PHY */
1448   TEST_ASSERT(eth_mac->Initialize(cb_event) == ARM_DRIVER_OK);
1449   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1450   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
1451     ARM_ETH_MAC_ADDRESS_BROADCAST | ARM_ETH_MAC_ADDRESS_ALL | ARM_ETH_MAC_LOOPBACK) == ARM_DRIVER_OK);
1452   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_RX, 1) == ARM_DRIVER_OK);
1453   TEST_ASSERT(eth_mac->Control(ARM_ETH_MAC_CONTROL_TX, 1) == ARM_DRIVER_OK);
1454   TEST_ASSERT(eth_phy->Initialize(eth_mac->PHY_Read, eth_mac->PHY_Write) == ARM_DRIVER_OK);
1455   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_FULL) == ARM_DRIVER_OK);
1456   osDelay (100);
1457   TEST_ASSERT(eth_phy->SetInterface(capab.media_interface) == ARM_DRIVER_OK);
1458   TEST_ASSERT(eth_phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE) == ARM_DRIVER_OK);
1459
1460   /* Set Time */
1461   time1.sec = 0U;
1462   time1.ns  = 0U;
1463   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_SET_TIME, &time1) == ARM_DRIVER_OK);
1464
1465   /* Check timestamps - verify if control timer is running */
1466   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time1) == ARM_DRIVER_OK);
1467   TEST_ASSERT(eth_mac->ControlTimer(ARM_ETH_MAC_TIMER_GET_TIME, &time2) == ARM_DRIVER_OK);
1468   TEST_ASSERT((time2.sec==time1.sec)?(time2.ns>time1.ns):(time2.sec>time1.sec));
1469
1470   /* Transfer frame */
1471   TEST_ASSERT(eth_mac->SendFrame(PTP_frame, PTP_frame_len, ARM_ETH_MAC_TX_FRAME_TIMESTAMP) == ARM_DRIVER_OK);
1472   tick = GET_SYSTICK();
1473   while (eth_mac->GetRxFrameSize() == 0) {
1474     if ((GET_SYSTICK() - tick) >= SYSTICK_MICROSEC(ETH_TRANSFER_TIMEOUT*1000)) {
1475       TEST_FAIL_MESSAGE("[FAILED] Transfer timeout");
1476       break;
1477     }
1478   }
1479
1480   /* Get TX Frame Time */
1481   TEST_ASSERT(eth_mac->GetTxFrameTime(&time1) == ARM_DRIVER_OK);
1482
1483   /* Get RX Frame Time */
1484   TEST_ASSERT(eth_mac->GetRxFrameTime(&time2) == ARM_DRIVER_OK);
1485
1486   /* Check timestamps */
1487   TEST_ASSERT((time2.sec==time1.sec) ? (time2.ns>time1.ns) : (time2.sec>time1.sec));
1488
1489   /* Check frame */
1490   eth_mac->ReadFrame(buffer_in, PTP_frame_len);
1491   TEST_ASSERT(memcmp(buffer_in, PTP_frame, PTP_frame_len) == 0);
1492
1493   /* Power off and uninitialize */
1494   TEST_ASSERT(eth_phy->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1495   TEST_ASSERT(eth_phy->Uninitialize() == ARM_DRIVER_OK);
1496   TEST_ASSERT(eth_mac->PowerControl(ARM_POWER_OFF) == ARM_DRIVER_OK);
1497   TEST_ASSERT(eth_mac->Uninitialize() == ARM_DRIVER_OK);
1498
1499   /* Free buffer */
1500   free(buffer_in);
1501 }
1502
1503
1504 /**
1505 @}
1506 */
1507 // end of group dv_eth