esp_eth_test_apps.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  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. // *** LAN8720 deviation ***
  146. // Rationale: When the device is in manual 100BASE-TX or 10BASE-T modes with Auto-MDIX enabled, the PHY does not link to a
  147. // link partner that is configured for auto-negotiation. See LAN8720 errata for more details.
  148. #ifdef CONFIG_TARGET_ETH_PHY_DEVICE_LAN8720
  149. esp_eth_phy_reg_rw_data_t reg;
  150. uint32_t reg_val;
  151. reg.reg_addr = 27;
  152. reg.reg_value_p = &reg_val;
  153. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_READ_PHY_REG, &reg));
  154. reg_val |= 0x8000;
  155. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_WRITE_PHY_REG, &reg));
  156. uint32_t reg_val_act;
  157. reg.reg_value_p = &reg_val_act;
  158. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_READ_PHY_REG, &reg));
  159. TEST_ASSERT_EQUAL(reg_val, reg_val_act);
  160. #endif
  161. // start the driver and wait for connection establish
  162. esp_eth_start(eth_handle);
  163. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  164. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  165. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  166. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  167. TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
  168. TEST_ASSERT_EQUAL(ETH_SPEED_10M, exp_speed);
  169. // Change speed back to 100 Mbps
  170. esp_eth_stop(eth_handle);
  171. ESP_LOGI(TAG, "change speed again...");
  172. speed = ETH_SPEED_100M;
  173. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
  174. // start the driver and wait for connection establish
  175. esp_eth_start(eth_handle);
  176. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  177. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  178. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  179. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  180. TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
  181. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  182. // Change duplex back to full
  183. esp_eth_stop(eth_handle);
  184. ESP_LOGI(TAG, "change duplex again...");
  185. duplex = ETH_DUPLEX_FULL;
  186. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
  187. // start the driver and wait for connection establish
  188. esp_eth_start(eth_handle);
  189. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  190. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  191. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  192. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  193. TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
  194. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  195. ESP_LOGI(TAG, "try to change speed/duplex when driver is started and autonegotiation disabled...");
  196. speed = ETH_SPEED_10M;
  197. duplex = ETH_DUPLEX_HALF;
  198. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
  199. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
  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_FULL, exp_duplex);
  203. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  204. ESP_LOGI(TAG, "change the speed/duplex to 10 Mbps/half and then enable autonegotiation...");
  205. esp_eth_stop(eth_handle);
  206. speed = ETH_SPEED_10M;
  207. duplex = ETH_DUPLEX_HALF;
  208. // set new duplex mode
  209. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
  210. // set new speed
  211. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
  212. // start the driver and wait for connection establish
  213. esp_eth_start(eth_handle);
  214. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  215. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  216. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  217. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  218. TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
  219. TEST_ASSERT_EQUAL(ETH_SPEED_10M, exp_speed);
  220. esp_eth_stop(eth_handle);
  221. auto_nego_en = true;
  222. esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en);
  223. // *** LAN8720 deviation ***
  224. // Rationale: See above
  225. #ifdef CONFIG_TARGET_ETH_PHY_DEVICE_LAN8720
  226. reg.reg_value_p = &reg_val;
  227. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_READ_PHY_REG, &reg));
  228. reg_val &= ~0x8000;
  229. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_WRITE_PHY_REG, &reg));
  230. reg.reg_value_p = &reg_val_act;
  231. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_READ_PHY_REG, &reg));
  232. TEST_ASSERT_EQUAL(reg_val, reg_val_act);
  233. #endif
  234. esp_eth_start(eth_handle);
  235. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  236. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  237. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
  238. TEST_ASSERT_EQUAL(true, exp_autoneg_en);
  239. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
  240. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
  241. // verify autonegotiation result (expecting the best link configuration)
  242. TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
  243. TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
  244. // stop Ethernet driver
  245. TEST_ESP_OK(esp_eth_stop(eth_handle));
  246. /* wait for connection stop */
  247. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  248. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  249. TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
  250. TEST_ESP_OK(phy->del(phy));
  251. TEST_ESP_OK(mac->del(mac));
  252. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  253. TEST_ESP_OK(esp_event_loop_delete_default());
  254. extra_cleanup();
  255. vEventGroupDelete(eth_event_group);
  256. }
  257. static SemaphoreHandle_t loopback_test_case_data_received;
  258. static esp_err_t loopback_test_case_incoming_handler(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv)
  259. {
  260. TEST_ASSERT(memcmp(priv, buffer, LOOPBACK_TEST_PACKET_SIZE) == 0)
  261. xSemaphoreGive(loopback_test_case_data_received);
  262. free(buffer);
  263. return ESP_OK;
  264. }
  265. TEST_CASE("ethernet io loopback", "[ethernet]")
  266. {
  267. loopback_test_case_data_received = xSemaphoreCreateBinary();
  268. // init everything else
  269. EventBits_t bits = 0;
  270. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  271. TEST_ASSERT(eth_event_group != NULL);
  272. TEST_ESP_OK(esp_event_loop_create_default());
  273. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  274. mac_config.flags = ETH_MAC_FLAG_PIN_TO_CORE; // pin to core
  275. esp_eth_mac_t *mac = mac_init(NULL, &mac_config);
  276. TEST_ASSERT_NOT_NULL(mac);
  277. esp_eth_phy_t *phy = phy_init(NULL);
  278. TEST_ASSERT_NOT_NULL(phy);
  279. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  280. esp_eth_handle_t eth_handle = NULL;
  281. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  282. extra_eth_config(eth_handle);
  283. // Disable autonegotiation to manually set speed and duplex mode
  284. bool auto_nego_en = false;
  285. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  286. bool loopback_en = true;
  287. // *** W5500 deviation ***
  288. // Rationale: does not support loopback
  289. #ifdef CONFIG_TARGET_ETH_PHY_DEVICE_W5500
  290. TEST_ASSERT(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en) == ESP_ERR_NOT_SUPPORTED);
  291. goto cleanup;
  292. #else
  293. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en));
  294. #endif
  295. eth_duplex_t duplex_modes[] = {ETH_DUPLEX_HALF, ETH_DUPLEX_FULL};
  296. eth_speed_t speeds[] = {ETH_SPEED_10M, ETH_SPEED_100M};
  297. emac_frame_t* test_packet = malloc(LOOPBACK_TEST_PACKET_SIZE);
  298. esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, test_packet->src);
  299. esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, test_packet->dest);
  300. for(size_t i = 0; i < LOOPBACK_TEST_PACKET_SIZE-ETH_HEADER_LEN; i++){
  301. test_packet->data[i] = rand() & 0xff;
  302. }
  303. TEST_ESP_OK(esp_eth_update_input_path(eth_handle, loopback_test_case_incoming_handler, test_packet));
  304. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  305. for (int i = 0; i < sizeof(speeds) / sizeof(eth_speed_t); i++) {
  306. eth_speed_t expected_speed = speeds[i];
  307. for (int j = 0; j < sizeof(duplex_modes) / sizeof(eth_duplex_t); j++) {
  308. eth_duplex_t expected_duplex = duplex_modes[j];
  309. ESP_LOGI(TAG, "Test with %s Mbps %s duplex.", expected_speed == ETH_SPEED_10M ? "10" : "100", expected_duplex == ETH_DUPLEX_HALF ? "half" : "full");
  310. // *** KSZ80XX, KSZ8851SNL and DM9051 deviation ***
  311. // Rationale: do not support loopback at 10 Mbps
  312. #if defined(CONFIG_TARGET_ETH_PHY_DEVICE_KSZ8041) || defined(CONFIG_TARGET_ETH_PHY_DEVICE_DM9051)
  313. if ((expected_speed == ETH_SPEED_10M)) {
  314. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &expected_speed));
  315. continue;
  316. } else if (expected_speed == ETH_SPEED_100M) {
  317. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &expected_speed));
  318. }
  319. #else
  320. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &expected_speed));
  321. #endif
  322. if ((expected_duplex == ETH_DUPLEX_HALF)) {
  323. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &expected_duplex));
  324. continue;
  325. } else if (expected_duplex == ETH_DUPLEX_FULL) {
  326. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &expected_duplex));
  327. }
  328. TEST_ESP_OK(esp_eth_start(eth_handle));
  329. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  330. eth_speed_t actual_speed = -1;
  331. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &actual_speed));
  332. TEST_ASSERT_EQUAL(expected_speed, actual_speed);
  333. eth_duplex_t actual_duplex = -1;
  334. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &actual_duplex));
  335. TEST_ASSERT_EQUAL(expected_duplex, actual_duplex);
  336. TEST_ESP_OK(esp_eth_transmit(eth_handle, test_packet, LOOPBACK_TEST_PACKET_SIZE));
  337. TEST_ASSERT(xSemaphoreTake(loopback_test_case_data_received, pdMS_TO_TICKS(10000)) == pdTRUE);
  338. TEST_ESP_OK(esp_eth_stop(eth_handle));
  339. }
  340. }
  341. // Test enabling autonegotiation when loopback is disabled
  342. ESP_LOGI(TAG, "Test enabling autonegotiation without loopback.");
  343. loopback_en = false;
  344. auto_nego_en = true;
  345. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en));
  346. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  347. auto_nego_en = false;
  348. loopback_en = true;
  349. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  350. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en));
  351. // Test with enabled autonegotiaton
  352. ESP_LOGI(TAG, "Test with enabled autonegotiation.");
  353. auto_nego_en = true;
  354. // *** RTL8201, DP83848 and LAN87xx deviation ***
  355. // Rationale: do not support autonegotiation with loopback enabled.
  356. #if defined(CONFIG_TARGET_ETH_PHY_DEVICE_RTL8201) || defined(CONFIG_TARGET_ETH_PHY_DEVICE_DP83848) || \
  357. defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN8720)
  358. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  359. goto cleanup;
  360. #endif
  361. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
  362. TEST_ESP_OK(esp_eth_start(eth_handle));
  363. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  364. TEST_ESP_OK(esp_eth_transmit(eth_handle, test_packet, LOOPBACK_TEST_PACKET_SIZE));
  365. TEST_ASSERT(xSemaphoreTake(loopback_test_case_data_received, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS)) == pdTRUE);
  366. free(test_packet);
  367. loopback_en = false;
  368. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en));
  369. TEST_ESP_OK(esp_eth_stop(eth_handle));
  370. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  371. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  372. // *** W5500, LAN87xx, RTL8201 and DP83848 deviation ***
  373. // 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
  374. #if defined(CONFIG_TARGET_ETH_PHY_DEVICE_W5500) || defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN8720) || \
  375. defined(CONFIG_TARGET_ETH_PHY_DEVICE_RTL8201) || defined(CONFIG_TARGET_ETH_PHY_DEVICE_DP83848)
  376. cleanup:
  377. #endif
  378. TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
  379. TEST_ESP_OK(phy->del(phy));
  380. TEST_ESP_OK(mac->del(mac));
  381. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  382. TEST_ESP_OK(esp_event_loop_delete_default());
  383. extra_cleanup();
  384. vEventGroupDelete(eth_event_group);
  385. }
  386. TEST_CASE("ethernet event test", "[ethernet]")
  387. {
  388. EventBits_t bits = 0;
  389. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  390. TEST_ASSERT(eth_event_group != NULL);
  391. TEST_ESP_OK(esp_event_loop_create_default());
  392. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  393. esp_eth_mac_t *mac = mac_init(NULL, NULL);
  394. TEST_ASSERT_NOT_NULL(mac);
  395. esp_eth_phy_t *phy = phy_init(NULL);
  396. TEST_ASSERT_NOT_NULL(phy);
  397. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  398. esp_eth_handle_t eth_handle = NULL;
  399. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  400. extra_eth_config(eth_handle);
  401. // this test only test layer2 event, so don't need to register input callback (i.e. esp_eth_update_input_path)
  402. TEST_ESP_OK(esp_eth_start(eth_handle));
  403. /* wait for connection start */
  404. bits = xEventGroupWaitBits(eth_event_group, ETH_START_BIT, true, true, pdMS_TO_TICKS(ETH_START_TIMEOUT_MS));
  405. TEST_ASSERT((bits & ETH_START_BIT) == ETH_START_BIT);
  406. /* wait for connection establish */
  407. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  408. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  409. // stop Ethernet driver
  410. TEST_ESP_OK(esp_eth_stop(eth_handle));
  411. /* wait for connection stop */
  412. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  413. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  414. /* driver should be uninstalled within 2 seconds */
  415. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  416. TEST_ESP_OK(phy->del(phy));
  417. TEST_ESP_OK(mac->del(mac));
  418. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  419. TEST_ESP_OK(esp_event_loop_delete_default());
  420. extra_cleanup();
  421. vEventGroupDelete(eth_event_group);
  422. }
  423. TEST_CASE("ethernet dhcp test", "[ethernet]")
  424. {
  425. EventBits_t bits = 0;
  426. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  427. TEST_ASSERT(eth_event_group != NULL);
  428. test_case_uses_tcpip();
  429. TEST_ESP_OK(esp_event_loop_create_default());
  430. // create TCP/IP netif
  431. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  432. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  433. esp_eth_mac_t *mac = mac_init(NULL, NULL);
  434. TEST_ASSERT_NOT_NULL(mac);
  435. esp_eth_phy_t *phy = phy_init(NULL);
  436. TEST_ASSERT_NOT_NULL(phy);
  437. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  438. esp_eth_handle_t eth_handle = NULL;
  439. // install Ethernet driver
  440. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  441. extra_eth_config(eth_handle);
  442. // combine driver with netif
  443. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  444. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  445. // register user defined event handers
  446. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  447. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  448. // start Ethernet driver
  449. TEST_ESP_OK(esp_eth_start(eth_handle));
  450. /* wait for IP lease */
  451. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  452. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  453. // stop Ethernet driver
  454. TEST_ESP_OK(esp_eth_stop(eth_handle));
  455. /* wait for connection stop */
  456. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  457. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  458. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  459. /* driver should be uninstalled within 2 seconds */
  460. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  461. TEST_ESP_OK(phy->del(phy));
  462. TEST_ESP_OK(mac->del(mac));
  463. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  464. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  465. esp_netif_destroy(eth_netif);
  466. TEST_ESP_OK(esp_event_loop_delete_default());
  467. extra_cleanup();
  468. vEventGroupDelete(eth_event_group);
  469. }
  470. TEST_CASE("ethernet start/stop stress test with IP stack", "[ethernet]")
  471. {
  472. EventBits_t bits = 0;
  473. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  474. TEST_ASSERT(eth_event_group != NULL);
  475. test_case_uses_tcpip();
  476. TEST_ESP_OK(esp_event_loop_create_default());
  477. // create TCP/IP netif
  478. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  479. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  480. esp_eth_mac_t *mac = mac_init(NULL, NULL);
  481. TEST_ASSERT_NOT_NULL(mac);
  482. esp_eth_phy_t *phy = phy_init(NULL);
  483. TEST_ASSERT_NOT_NULL(phy);
  484. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  485. esp_eth_handle_t eth_handle = NULL;
  486. // install Ethernet driver
  487. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  488. extra_eth_config(eth_handle);
  489. // combine driver with netif
  490. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  491. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  492. // register user defined event handers
  493. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  494. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  495. for (int i = 0; i < 10; i++) {
  496. // start Ethernet driver
  497. TEST_ESP_OK(esp_eth_start(eth_handle));
  498. /* wait for IP lease */
  499. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  500. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  501. // stop Ethernet driver
  502. TEST_ESP_OK(esp_eth_stop(eth_handle));
  503. /* wait for connection stop */
  504. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  505. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  506. }
  507. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  508. /* driver should be uninstalled within 2 seconds */
  509. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  510. TEST_ESP_OK(phy->del(phy));
  511. TEST_ESP_OK(mac->del(mac));
  512. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  513. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  514. esp_netif_destroy(eth_netif);
  515. TEST_ESP_OK(esp_event_loop_delete_default());
  516. extra_cleanup();
  517. vEventGroupDelete(eth_event_group);
  518. }
  519. esp_err_t http_event_handle(esp_http_client_event_t *evt)
  520. {
  521. switch (evt->event_id) {
  522. case HTTP_EVENT_ERROR:
  523. ESP_LOGE(TAG, "HTTP_EVENT_ERROR");
  524. break;
  525. case HTTP_EVENT_ON_CONNECTED:
  526. ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
  527. break;
  528. case HTTP_EVENT_HEADER_SENT:
  529. ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
  530. break;
  531. case HTTP_EVENT_ON_HEADER:
  532. ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER");
  533. break;
  534. case HTTP_EVENT_ON_DATA:
  535. esp_rom_md5_update(&md5_context, evt->data, evt->data_len);
  536. break;
  537. case HTTP_EVENT_ON_FINISH:
  538. ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");
  539. break;
  540. case HTTP_EVENT_DISCONNECTED:
  541. ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
  542. break;
  543. case HTTP_EVENT_REDIRECT:
  544. ESP_LOGI(TAG, "HTTP_EVENT_REDIRECT");
  545. break;
  546. }
  547. return ESP_OK;
  548. }
  549. static void eth_start_download(void)
  550. {
  551. esp_rom_md5_init(&md5_context);
  552. esp_http_client_config_t config = {
  553. .url = "https://dl.espressif.com/dl/misc/2MB.bin",
  554. .cert_pem = dl_espressif_com_root_cert_pem_start,
  555. .event_handler = http_event_handle,
  556. .buffer_size = 5120
  557. };
  558. esp_http_client_handle_t client = esp_http_client_init(&config);
  559. TEST_ASSERT_NOT_NULL(client);
  560. TEST_ESP_OK(esp_http_client_perform(client));
  561. TEST_ESP_OK(esp_http_client_cleanup(client));
  562. esp_rom_md5_final(digest, &md5_context);
  563. }
  564. TEST_CASE("ethernet download test", "[ethernet]")
  565. {
  566. EventBits_t bits = 0;
  567. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  568. TEST_ASSERT(eth_event_group != NULL);
  569. test_case_uses_tcpip();
  570. TEST_ESP_OK(esp_event_loop_create_default());
  571. // create TCP/IP netif
  572. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  573. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  574. esp_eth_mac_t *mac = mac_init(NULL, NULL);
  575. TEST_ASSERT_NOT_NULL(mac);
  576. esp_eth_phy_t *phy = phy_init(NULL);
  577. TEST_ASSERT_NOT_NULL(phy);
  578. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  579. esp_eth_handle_t eth_handle = NULL;
  580. // install Ethernet driver
  581. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  582. extra_eth_config(eth_handle);
  583. // combine driver with netif
  584. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  585. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  586. // register user defined event handers
  587. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  588. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  589. // start Ethernet driver
  590. TEST_ESP_OK(esp_eth_start(eth_handle));
  591. /* wait for IP lease */
  592. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  593. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  594. eth_start_download();
  595. // check MD5 digest
  596. // MD5: df61db8564d145bbe67112aa8ecdccd8
  597. uint8_t expect_digest[16] = {223, 97, 219, 133, 100, 209, 69, 187, 230, 113, 18, 170, 142, 205, 204, 216};
  598. printf("MD5 Digest: ");
  599. for (int i = 0; i < 16; i++) {
  600. printf("%d ", digest[i]);
  601. }
  602. printf("\r\n");
  603. TEST_ASSERT_EQUAL_UINT8_ARRAY(expect_digest, digest, sizeof(digest));
  604. // stop Ethernet driver
  605. TEST_ESP_OK(esp_eth_stop(eth_handle));
  606. /* wait for connection stop */
  607. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  608. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  609. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  610. /* driver should be uninstalled within 2 seconds */
  611. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  612. TEST_ESP_OK(phy->del(phy));
  613. TEST_ESP_OK(mac->del(mac));
  614. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  615. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  616. esp_netif_destroy(eth_netif);
  617. TEST_ESP_OK(esp_event_loop_delete_default());
  618. extra_cleanup();
  619. vEventGroupDelete(eth_event_group);
  620. }