esp_eth_test_apps.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <inttypes.h>
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "freertos/event_groups.h"
  12. #include "esp_log.h"
  13. #include "esp_http_client.h"
  14. #include "esp_rom_md5.h"
  15. #include "esp_eth_test_common.h"
  16. #define LOOPBACK_TEST_PACKET_SIZE 256
  17. static const char *TAG = "esp32_eth_test";
  18. extern const char dl_espressif_com_root_cert_pem_start[] asm("_binary_dl_espressif_com_root_cert_pem_start");
  19. extern const char dl_espressif_com_root_cert_pem_end[] asm("_binary_dl_espressif_com_root_cert_pem_end");
  20. // compute md5 of download file
  21. static md5_context_t md5_context;
  22. static uint8_t digest[16];
  23. static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_wait)
  24. {
  25. int i = 0;
  26. ms_to_wait += 100;
  27. for (i = 0; i < ms_to_wait / 100; i++) {
  28. vTaskDelay(pdMS_TO_TICKS(100));
  29. if (esp_eth_driver_uninstall(eth_hdl) == ESP_OK) {
  30. break;
  31. }
  32. }
  33. if (i < ms_to_wait / 100) {
  34. return ESP_OK;
  35. } else {
  36. return ESP_FAIL;
  37. }
  38. }
  39. TEST_CASE("ethernet io test", "[ethernet]")
  40. {
  41. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  42. mac_config.flags = ETH_MAC_FLAG_PIN_TO_CORE; // pin to core
  43. esp_eth_mac_t *mac = mac_init(NULL, &mac_config);
  44. TEST_ASSERT_NOT_NULL(mac);
  45. esp_eth_phy_t *phy = phy_init(NULL);
  46. TEST_ASSERT_NOT_NULL(phy);
  47. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  48. esp_eth_handle_t eth_handle = NULL;
  49. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  50. extra_eth_config(eth_handle);
  51. /* get default MAC address */
  52. uint8_t mac_addr[ETH_ADDR_LEN];
  53. memset(mac_addr, 0, sizeof(mac_addr));
  54. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr));
  55. ESP_LOGI(TAG, "Ethernet MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
  56. mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  57. TEST_ASSERT(mac_addr[0] != 0);
  58. // *** SPI Ethernet modules deviation ***
  59. // Rationale: The SPI Ethernet modules don't have a burned default factory MAC address hence local MAC is used
  60. #if !CONFIG_TARGET_USE_SPI_ETHERNET
  61. TEST_ASSERT_BITS(0b00000011, 0b00, mac_addr[0]); // Check UL&IG, should be UI
  62. #endif
  63. /* set different MAC address */
  64. mac_addr[5] ^= mac_addr[4];
  65. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, mac_addr));
  66. /* get new MAC address */
  67. uint8_t mac_addr_new[ETH_ADDR_LEN] = { 0 };
  68. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr_new));
  69. ESP_LOGI(TAG, "Ethernet MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
  70. mac_addr_new[0], mac_addr_new[1], mac_addr_new[2], mac_addr_new[3], mac_addr_new[4], mac_addr_new[5]);
  71. TEST_ASSERT_EQUAL_UINT8_ARRAY(mac_addr_new, mac_addr, ETH_ADDR_LEN);
  72. // *** SPI Ethernet modules deviation ***
  73. // Rationale: SPI Ethernet modules PHYs and MACs are statically configured at one die, hence there is no need for PHY address
  74. // from user's point of view
  75. #if !CONFIG_TARGET_USE_SPI_ETHERNET
  76. /* get PHY address */
  77. int phy_addr = -1;
  78. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_PHY_ADDR, &phy_addr));
  79. ESP_LOGI(TAG, "Ethernet PHY Address: %d", phy_addr);
  80. TEST_ASSERT(phy_addr >= 0 && phy_addr <= 31);
  81. #endif
  82. TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
  83. TEST_ESP_OK(phy->del(phy));
  84. TEST_ESP_OK(mac->del(mac));
  85. extra_cleanup();
  86. }
  87. // This test expects autonegotiation to be enabled on the other node.
  88. TEST_CASE("ethernet io speed/duplex/autonegotiation", "[ethernet]")
  89. {
  90. EventBits_t bits = 0;
  91. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  92. TEST_ASSERT(eth_event_group != NULL);
  93. TEST_ESP_OK(esp_event_loop_create_default());
  94. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  95. mac_config.flags = ETH_MAC_FLAG_PIN_TO_CORE; // pin to core
  96. esp_eth_mac_t *mac = mac_init(NULL, &mac_config);
  97. TEST_ASSERT_NOT_NULL(mac);
  98. esp_eth_phy_t *phy = phy_init(NULL);
  99. TEST_ASSERT_NOT_NULL(phy);
  100. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  101. esp_eth_handle_t eth_handle = NULL;
  102. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  103. extra_eth_config(eth_handle);
  104. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  105. // this test only test layer2, so don't need to register input callback (i.e. esp_eth_update_input_path)
  106. TEST_ESP_OK(esp_eth_start(eth_handle));
  107. // wait for connection start
  108. bits = xEventGroupWaitBits(eth_event_group, ETH_START_BIT, true, true, pdMS_TO_TICKS(ETH_START_TIMEOUT_MS));
  109. TEST_ASSERT((bits & ETH_START_BIT) == ETH_START_BIT);
  110. // wait for connection establish
  111. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  112. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  113. eth_duplex_t exp_duplex;
  114. esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex);
  115. eth_speed_t exp_speed;
  116. esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed);
  117. // verify autonegotiation result (expecting the best link configuration)
  118. TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
  119. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  120. bool exp_autoneg_en;
  121. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
  122. TEST_ASSERT_EQUAL(true, exp_autoneg_en);
  123. ESP_LOGI(TAG, "try to change autonegotiation when driver is started...");
  124. bool auto_nego_en = false;
  125. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  126. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
  127. TEST_ASSERT_EQUAL(true, exp_autoneg_en);
  128. ESP_LOGI(TAG, "stop the Ethernet driver and...");
  129. esp_eth_stop(eth_handle);
  130. ESP_LOGI(TAG, "try to change speed/duplex prior disabling the autonegotiation...");
  131. eth_duplex_t duplex = ETH_DUPLEX_HALF;
  132. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
  133. eth_speed_t speed = ETH_SPEED_10M;
  134. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
  135. // Disable autonegotiation and change speed to 10 Mbps and duplex to half
  136. ESP_LOGI(TAG, "disable the autonegotiation and change the speed/duplex...");
  137. auto_nego_en = false;
  138. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  139. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
  140. TEST_ASSERT_EQUAL(false, exp_autoneg_en);
  141. // set new duplex mode
  142. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
  143. // set new speed
  144. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
  145. // start the driver and wait for connection establish
  146. esp_eth_start(eth_handle);
  147. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  148. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  149. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  150. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  151. TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
  152. TEST_ASSERT_EQUAL(ETH_SPEED_10M, exp_speed);
  153. // Change speed back to 100 Mbps
  154. esp_eth_stop(eth_handle);
  155. ESP_LOGI(TAG, "change speed again...");
  156. speed = ETH_SPEED_100M;
  157. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
  158. // start the driver and wait for connection establish
  159. esp_eth_start(eth_handle);
  160. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  161. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  162. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  163. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  164. TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
  165. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  166. // Change duplex back to full
  167. esp_eth_stop(eth_handle);
  168. ESP_LOGI(TAG, "change duplex again...");
  169. duplex = ETH_DUPLEX_FULL;
  170. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
  171. // start the driver and wait for connection establish
  172. esp_eth_start(eth_handle);
  173. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  174. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  175. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  176. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  177. TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
  178. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  179. ESP_LOGI(TAG, "try to change speed/duplex when driver is started and autonegotiation disabled...");
  180. speed = ETH_SPEED_10M;
  181. duplex = ETH_DUPLEX_HALF;
  182. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
  183. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
  184. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  185. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  186. TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
  187. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  188. ESP_LOGI(TAG, "change the speed/duplex to 10 Mbps/half and then enable autonegotiation...");
  189. esp_eth_stop(eth_handle);
  190. speed = ETH_SPEED_10M;
  191. duplex = ETH_DUPLEX_HALF;
  192. // set new duplex mode
  193. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
  194. // set new speed
  195. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
  196. // start the driver and wait for connection establish
  197. esp_eth_start(eth_handle);
  198. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  199. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  200. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  201. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  202. TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
  203. TEST_ASSERT_EQUAL(ETH_SPEED_10M, exp_speed);
  204. esp_eth_stop(eth_handle);
  205. auto_nego_en = true;
  206. esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en);
  207. esp_eth_start(eth_handle);
  208. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  209. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  210. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
  211. TEST_ASSERT_EQUAL(true, exp_autoneg_en);
  212. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  213. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  214. // verify autonegotiation result (expecting the best link configuration)
  215. TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
  216. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  217. // stop Ethernet driver
  218. TEST_ESP_OK(esp_eth_stop(eth_handle));
  219. /* wait for connection stop */
  220. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  221. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  222. TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
  223. TEST_ESP_OK(phy->del(phy));
  224. TEST_ESP_OK(mac->del(mac));
  225. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  226. TEST_ESP_OK(esp_event_loop_delete_default());
  227. extra_cleanup();
  228. vEventGroupDelete(eth_event_group);
  229. }
  230. static SemaphoreHandle_t loopback_test_case_data_received;
  231. static esp_err_t loopback_test_case_incoming_handler(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv)
  232. {
  233. TEST_ASSERT(memcmp(priv, buffer, LOOPBACK_TEST_PACKET_SIZE) == 0)
  234. xSemaphoreGive(loopback_test_case_data_received);
  235. free(buffer);
  236. return ESP_OK;
  237. }
  238. TEST_CASE("ethernet io loopback", "[ethernet]")
  239. {
  240. loopback_test_case_data_received = xSemaphoreCreateBinary();
  241. // init everything else
  242. EventBits_t bits = 0;
  243. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  244. TEST_ASSERT(eth_event_group != NULL);
  245. TEST_ESP_OK(esp_event_loop_create_default());
  246. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  247. mac_config.flags = ETH_MAC_FLAG_PIN_TO_CORE; // pin to core
  248. esp_eth_mac_t *mac = mac_init(NULL, &mac_config);
  249. TEST_ASSERT_NOT_NULL(mac);
  250. esp_eth_phy_t *phy = phy_init(NULL);
  251. TEST_ASSERT_NOT_NULL(phy);
  252. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  253. esp_eth_handle_t eth_handle = NULL;
  254. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  255. extra_eth_config(eth_handle);
  256. // Disable autonegotiation to manually set speed and duplex mode
  257. bool auto_nego_en = false;
  258. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  259. bool loopback_en = true;
  260. // *** W5500 deviation ***
  261. // Rationale: does not support loopback
  262. #ifdef CONFIG_TARGET_ETH_PHY_DEVICE_W5500
  263. TEST_ASSERT(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en) == ESP_ERR_NOT_SUPPORTED);
  264. goto cleanup;
  265. #else
  266. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en));
  267. #endif
  268. eth_duplex_t duplex_modes[] = {ETH_DUPLEX_HALF, ETH_DUPLEX_FULL};
  269. eth_speed_t speeds[] = {ETH_SPEED_10M, ETH_SPEED_100M};
  270. emac_frame_t* test_packet = malloc(LOOPBACK_TEST_PACKET_SIZE);
  271. esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, test_packet->src);
  272. esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, test_packet->dest);
  273. for(size_t i = 0; i < LOOPBACK_TEST_PACKET_SIZE-ETH_HEADER_LEN; i++){
  274. test_packet->data[i] = rand() & 0xff;
  275. }
  276. TEST_ESP_OK(esp_eth_update_input_path(eth_handle, loopback_test_case_incoming_handler, test_packet));
  277. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  278. for (int i = 0; i < sizeof(speeds) / sizeof(eth_speed_t); i++) {
  279. eth_speed_t expected_speed = speeds[i];
  280. for (int j = 0; j < sizeof(duplex_modes) / sizeof(eth_duplex_t); j++) {
  281. eth_duplex_t expected_duplex = duplex_modes[j];
  282. ESP_LOGI(TAG, "Test with %s Mbps %s duplex.", expected_speed == ETH_SPEED_10M ? "10" : "100", expected_duplex == ETH_DUPLEX_HALF ? "half" : "full");
  283. // *** KSZ80XX, KSZ8851SNL and DM9051 deviation ***
  284. // Rationale: do not support loopback at 10 Mbps
  285. #if defined(CONFIG_TARGET_ETH_PHY_DEVICE_KSZ80XX) || defined(CONFIG_TARGET_ETH_PHY_DEVICE_DM9051)
  286. if ((expected_speed == ETH_SPEED_10M)) {
  287. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &expected_speed));
  288. continue;
  289. } else if (expected_speed == ETH_SPEED_100M) {
  290. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &expected_speed));
  291. }
  292. #else
  293. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &expected_speed));
  294. #endif
  295. if ((expected_duplex == ETH_DUPLEX_HALF)) {
  296. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &expected_duplex));
  297. continue;
  298. } else if (expected_duplex == ETH_DUPLEX_FULL) {
  299. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &expected_duplex));
  300. }
  301. TEST_ESP_OK(esp_eth_start(eth_handle));
  302. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  303. eth_speed_t actual_speed = -1;
  304. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &actual_speed));
  305. TEST_ASSERT_EQUAL(expected_speed, actual_speed);
  306. eth_duplex_t actual_duplex = -1;
  307. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &actual_duplex));
  308. TEST_ASSERT_EQUAL(expected_duplex, actual_duplex);
  309. TEST_ESP_OK(esp_eth_transmit(eth_handle, test_packet, LOOPBACK_TEST_PACKET_SIZE));
  310. TEST_ASSERT(xSemaphoreTake(loopback_test_case_data_received, pdMS_TO_TICKS(10000)) == pdTRUE);
  311. TEST_ESP_OK(esp_eth_stop(eth_handle));
  312. }
  313. }
  314. // Test enabling autonegotiation when loopback is disabled
  315. ESP_LOGI(TAG, "Test enabling autonegotiation without loopback.");
  316. loopback_en = false;
  317. auto_nego_en = true;
  318. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en));
  319. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  320. auto_nego_en = false;
  321. loopback_en = true;
  322. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  323. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en));
  324. // Test with enabled autonegotiaton
  325. ESP_LOGI(TAG, "Test with enabled autonegotiation.");
  326. auto_nego_en = true;
  327. // *** RTL8201, DP83848 and LAN87xx deviation ***
  328. // Rationale: do not support autonegotiation with loopback enabled.
  329. #if defined(CONFIG_TARGET_ETH_PHY_DEVICE_RTL8201) || defined(CONFIG_TARGET_ETH_PHY_DEVICE_DP83848) || \
  330. defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX)
  331. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  332. goto cleanup;
  333. #endif
  334. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  335. TEST_ESP_OK(esp_eth_start(eth_handle));
  336. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  337. TEST_ESP_OK(esp_eth_transmit(eth_handle, test_packet, LOOPBACK_TEST_PACKET_SIZE));
  338. TEST_ASSERT(xSemaphoreTake(loopback_test_case_data_received, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS)) == pdTRUE);
  339. free(test_packet);
  340. loopback_en = false;
  341. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en));
  342. TEST_ESP_OK(esp_eth_stop(eth_handle));
  343. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  344. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  345. // *** W5500, LAN87xx, RTL8201 and DP83848 deviation ***
  346. // Rationale: in those cases 'goto cleanup' is used to skip part of the test code. Incasing in #if block is done to prevent unused label error
  347. #if defined(CONFIG_TARGET_ETH_PHY_DEVICE_W5500) || defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX) || \
  348. defined(CONFIG_TARGET_ETH_PHY_DEVICE_RTL8201) || defined(CONFIG_TARGET_ETH_PHY_DEVICE_DP83848)
  349. cleanup:
  350. #endif
  351. TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
  352. TEST_ESP_OK(phy->del(phy));
  353. TEST_ESP_OK(mac->del(mac));
  354. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  355. TEST_ESP_OK(esp_event_loop_delete_default());
  356. extra_cleanup();
  357. vEventGroupDelete(eth_event_group);
  358. }
  359. TEST_CASE("ethernet event test", "[ethernet]")
  360. {
  361. EventBits_t bits = 0;
  362. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  363. TEST_ASSERT(eth_event_group != NULL);
  364. TEST_ESP_OK(esp_event_loop_create_default());
  365. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  366. esp_eth_mac_t *mac = mac_init(NULL, NULL);
  367. TEST_ASSERT_NOT_NULL(mac);
  368. esp_eth_phy_t *phy = phy_init(NULL);
  369. TEST_ASSERT_NOT_NULL(phy);
  370. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  371. esp_eth_handle_t eth_handle = NULL;
  372. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  373. extra_eth_config(eth_handle);
  374. // this test only test layer2 event, so don't need to register input callback (i.e. esp_eth_update_input_path)
  375. TEST_ESP_OK(esp_eth_start(eth_handle));
  376. /* wait for connection start */
  377. bits = xEventGroupWaitBits(eth_event_group, ETH_START_BIT, true, true, pdMS_TO_TICKS(ETH_START_TIMEOUT_MS));
  378. TEST_ASSERT((bits & ETH_START_BIT) == ETH_START_BIT);
  379. /* wait for connection establish */
  380. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  381. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  382. // stop Ethernet driver
  383. TEST_ESP_OK(esp_eth_stop(eth_handle));
  384. /* wait for connection stop */
  385. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  386. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  387. /* driver should be uninstalled within 2 seconds */
  388. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  389. TEST_ESP_OK(phy->del(phy));
  390. TEST_ESP_OK(mac->del(mac));
  391. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  392. TEST_ESP_OK(esp_event_loop_delete_default());
  393. extra_cleanup();
  394. vEventGroupDelete(eth_event_group);
  395. }
  396. TEST_CASE("ethernet dhcp test", "[ethernet]")
  397. {
  398. EventBits_t bits = 0;
  399. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  400. TEST_ASSERT(eth_event_group != NULL);
  401. test_case_uses_tcpip();
  402. TEST_ESP_OK(esp_event_loop_create_default());
  403. // create TCP/IP netif
  404. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  405. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  406. esp_eth_mac_t *mac = mac_init(NULL, NULL);
  407. TEST_ASSERT_NOT_NULL(mac);
  408. esp_eth_phy_t *phy = phy_init(NULL);
  409. TEST_ASSERT_NOT_NULL(phy);
  410. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  411. esp_eth_handle_t eth_handle = NULL;
  412. // install Ethernet driver
  413. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  414. extra_eth_config(eth_handle);
  415. // combine driver with netif
  416. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  417. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  418. // register user defined event handers
  419. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  420. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  421. // start Ethernet driver
  422. TEST_ESP_OK(esp_eth_start(eth_handle));
  423. /* wait for IP lease */
  424. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  425. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  426. // stop Ethernet driver
  427. TEST_ESP_OK(esp_eth_stop(eth_handle));
  428. /* wait for connection stop */
  429. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  430. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  431. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  432. /* driver should be uninstalled within 2 seconds */
  433. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  434. TEST_ESP_OK(phy->del(phy));
  435. TEST_ESP_OK(mac->del(mac));
  436. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  437. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  438. esp_netif_destroy(eth_netif);
  439. TEST_ESP_OK(esp_event_loop_delete_default());
  440. extra_cleanup();
  441. vEventGroupDelete(eth_event_group);
  442. }
  443. TEST_CASE("ethernet start/stop stress test with IP stack", "[ethernet]")
  444. {
  445. EventBits_t bits = 0;
  446. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  447. TEST_ASSERT(eth_event_group != NULL);
  448. test_case_uses_tcpip();
  449. TEST_ESP_OK(esp_event_loop_create_default());
  450. // create TCP/IP netif
  451. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  452. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  453. esp_eth_mac_t *mac = mac_init(NULL, NULL);
  454. TEST_ASSERT_NOT_NULL(mac);
  455. esp_eth_phy_t *phy = phy_init(NULL);
  456. TEST_ASSERT_NOT_NULL(phy);
  457. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  458. esp_eth_handle_t eth_handle = NULL;
  459. // install Ethernet driver
  460. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  461. extra_eth_config(eth_handle);
  462. // combine driver with netif
  463. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  464. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  465. // register user defined event handers
  466. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  467. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  468. for (int i = 0; i < 10; i++) {
  469. // start Ethernet driver
  470. TEST_ESP_OK(esp_eth_start(eth_handle));
  471. /* wait for IP lease */
  472. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  473. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  474. // stop Ethernet driver
  475. TEST_ESP_OK(esp_eth_stop(eth_handle));
  476. /* wait for connection stop */
  477. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  478. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  479. }
  480. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  481. /* driver should be uninstalled within 2 seconds */
  482. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  483. TEST_ESP_OK(phy->del(phy));
  484. TEST_ESP_OK(mac->del(mac));
  485. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  486. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  487. esp_netif_destroy(eth_netif);
  488. TEST_ESP_OK(esp_event_loop_delete_default());
  489. extra_cleanup();
  490. vEventGroupDelete(eth_event_group);
  491. }
  492. esp_err_t http_event_handle(esp_http_client_event_t *evt)
  493. {
  494. switch (evt->event_id) {
  495. case HTTP_EVENT_ERROR:
  496. ESP_LOGE(TAG, "HTTP_EVENT_ERROR");
  497. break;
  498. case HTTP_EVENT_ON_CONNECTED:
  499. ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
  500. break;
  501. case HTTP_EVENT_HEADER_SENT:
  502. ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
  503. break;
  504. case HTTP_EVENT_ON_HEADER:
  505. ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER");
  506. break;
  507. case HTTP_EVENT_ON_DATA:
  508. esp_rom_md5_update(&md5_context, evt->data, evt->data_len);
  509. break;
  510. case HTTP_EVENT_ON_FINISH:
  511. ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");
  512. break;
  513. case HTTP_EVENT_DISCONNECTED:
  514. ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
  515. break;
  516. case HTTP_EVENT_REDIRECT:
  517. ESP_LOGI(TAG, "HTTP_EVENT_REDIRECT");
  518. break;
  519. }
  520. return ESP_OK;
  521. }
  522. static void eth_start_download(void)
  523. {
  524. esp_rom_md5_init(&md5_context);
  525. esp_http_client_config_t config = {
  526. .url = "https://dl.espressif.com/dl/misc/2MB.bin",
  527. .cert_pem = dl_espressif_com_root_cert_pem_start,
  528. .event_handler = http_event_handle,
  529. .buffer_size = 5120
  530. };
  531. esp_http_client_handle_t client = esp_http_client_init(&config);
  532. TEST_ASSERT_NOT_NULL(client);
  533. TEST_ESP_OK(esp_http_client_perform(client));
  534. TEST_ESP_OK(esp_http_client_cleanup(client));
  535. esp_rom_md5_final(digest, &md5_context);
  536. }
  537. TEST_CASE("ethernet download test", "[ethernet]")
  538. {
  539. EventBits_t bits = 0;
  540. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  541. TEST_ASSERT(eth_event_group != NULL);
  542. test_case_uses_tcpip();
  543. TEST_ESP_OK(esp_event_loop_create_default());
  544. // create TCP/IP netif
  545. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  546. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  547. esp_eth_mac_t *mac = mac_init(NULL, NULL);
  548. TEST_ASSERT_NOT_NULL(mac);
  549. esp_eth_phy_t *phy = phy_init(NULL);
  550. TEST_ASSERT_NOT_NULL(phy);
  551. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  552. esp_eth_handle_t eth_handle = NULL;
  553. // install Ethernet driver
  554. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  555. extra_eth_config(eth_handle);
  556. // combine driver with netif
  557. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  558. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  559. // register user defined event handers
  560. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  561. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  562. // start Ethernet driver
  563. TEST_ESP_OK(esp_eth_start(eth_handle));
  564. /* wait for IP lease */
  565. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  566. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  567. eth_start_download();
  568. // check MD5 digest
  569. // MD5: df61db8564d145bbe67112aa8ecdccd8
  570. uint8_t expect_digest[16] = {223, 97, 219, 133, 100, 209, 69, 187, 230, 113, 18, 170, 142, 205, 204, 216};
  571. printf("MD5 Digest: ");
  572. for (int i = 0; i < 16; i++) {
  573. printf("%d ", digest[i]);
  574. }
  575. printf("\r\n");
  576. TEST_ASSERT_EQUAL_UINT8_ARRAY(expect_digest, digest, sizeof(digest));
  577. // stop Ethernet driver
  578. TEST_ESP_OK(esp_eth_stop(eth_handle));
  579. /* wait for connection stop */
  580. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  581. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  582. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  583. /* driver should be uninstalled within 2 seconds */
  584. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  585. TEST_ESP_OK(phy->del(phy));
  586. TEST_ESP_OK(mac->del(mac));
  587. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  588. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  589. esp_netif_destroy(eth_netif);
  590. TEST_ESP_OK(esp_event_loop_delete_default());
  591. extra_cleanup();
  592. vEventGroupDelete(eth_event_group);
  593. }