connect.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. /* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <string.h>
  8. #include "protocol_examples_common.h"
  9. #include "sdkconfig.h"
  10. #include "esp_event.h"
  11. #include "esp_wifi.h"
  12. #include "esp_wifi_default.h"
  13. #if CONFIG_EXAMPLE_CONNECT_ETHERNET
  14. #include "esp_eth.h"
  15. #if CONFIG_ETH_USE_SPI_ETHERNET
  16. #include "driver/spi_master.h"
  17. #endif // CONFIG_ETH_USE_SPI_ETHERNET
  18. #endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
  19. #include "esp_log.h"
  20. #include "esp_netif.h"
  21. #include "driver/gpio.h"
  22. #include "freertos/FreeRTOS.h"
  23. #include "freertos/task.h"
  24. #include "freertos/event_groups.h"
  25. #include "lwip/err.h"
  26. #include "lwip/sys.h"
  27. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  28. #define MAX_IP6_ADDRS_PER_NETIF (5)
  29. #define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (s_active_interfaces*2)
  30. #if defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK)
  31. #define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_LINK_LOCAL
  32. #elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL)
  33. #define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_GLOBAL
  34. #elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL)
  35. #define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_SITE_LOCAL
  36. #elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL)
  37. #define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_UNIQUE_LOCAL
  38. #endif // if-elif CONFIG_EXAMPLE_CONNECT_IPV6_PREF_...
  39. #else
  40. #define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (s_active_interfaces)
  41. #endif
  42. #define EXAMPLE_DO_CONNECT CONFIG_EXAMPLE_CONNECT_WIFI || CONFIG_EXAMPLE_CONNECT_ETHERNET
  43. #if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST
  44. #define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN
  45. #elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
  46. #define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN
  47. #endif
  48. #if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
  49. #define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
  50. #elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
  51. #define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY
  52. #endif
  53. #if CONFIG_EXAMPLE_WIFI_AUTH_OPEN
  54. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
  55. #elif CONFIG_EXAMPLE_WIFI_AUTH_WEP
  56. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
  57. #elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK
  58. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
  59. #elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK
  60. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
  61. #elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
  62. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
  63. #elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
  64. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE
  65. #elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK
  66. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
  67. #elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
  68. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
  69. #elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK
  70. #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
  71. #endif
  72. static int s_active_interfaces = 0;
  73. static xSemaphoreHandle s_semph_get_ip_addrs;
  74. static esp_netif_t *s_example_esp_netif = NULL;
  75. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  76. static esp_ip6_addr_t s_ipv6_addr;
  77. /* types of ipv6 addresses to be displayed on ipv6 events */
  78. static const char *s_ipv6_addr_types[] = {
  79. "ESP_IP6_ADDR_IS_UNKNOWN",
  80. "ESP_IP6_ADDR_IS_GLOBAL",
  81. "ESP_IP6_ADDR_IS_LINK_LOCAL",
  82. "ESP_IP6_ADDR_IS_SITE_LOCAL",
  83. "ESP_IP6_ADDR_IS_UNIQUE_LOCAL",
  84. "ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6"
  85. };
  86. #endif
  87. static const char *TAG = "example_connect";
  88. #if CONFIG_EXAMPLE_CONNECT_WIFI
  89. static esp_netif_t *wifi_start(void);
  90. static void wifi_stop(void);
  91. #endif
  92. #if CONFIG_EXAMPLE_CONNECT_ETHERNET
  93. static esp_netif_t *eth_start(void);
  94. static void eth_stop(void);
  95. #endif
  96. /**
  97. * @brief Checks the netif description if it contains specified prefix.
  98. * All netifs created withing common connect component are prefixed with the module TAG,
  99. * so it returns true if the specified netif is owned by this module
  100. */
  101. static bool is_our_netif(const char *prefix, esp_netif_t *netif)
  102. {
  103. return strncmp(prefix, esp_netif_get_desc(netif), strlen(prefix) - 1) == 0;
  104. }
  105. /* set up connection, Wi-Fi and/or Ethernet */
  106. static void start(void)
  107. {
  108. #if CONFIG_EXAMPLE_CONNECT_WIFI
  109. s_example_esp_netif = wifi_start();
  110. s_active_interfaces++;
  111. #endif
  112. #if CONFIG_EXAMPLE_CONNECT_ETHERNET
  113. s_example_esp_netif = eth_start();
  114. s_active_interfaces++;
  115. #endif
  116. #if CONFIG_EXAMPLE_CONNECT_WIFI && CONFIG_EXAMPLE_CONNECT_ETHERNET
  117. /* if both intefaces at once, clear out to indicate that multiple netifs are active */
  118. s_example_esp_netif = NULL;
  119. #endif
  120. #if EXAMPLE_DO_CONNECT
  121. /* create semaphore if at least one interface is active */
  122. s_semph_get_ip_addrs = xSemaphoreCreateCounting(NR_OF_IP_ADDRESSES_TO_WAIT_FOR, 0);
  123. #endif
  124. }
  125. /* tear down connection, release resources */
  126. static void stop(void)
  127. {
  128. #if CONFIG_EXAMPLE_CONNECT_WIFI
  129. wifi_stop();
  130. s_active_interfaces--;
  131. #endif
  132. #if CONFIG_EXAMPLE_CONNECT_ETHERNET
  133. eth_stop();
  134. s_active_interfaces--;
  135. #endif
  136. }
  137. #if EXAMPLE_DO_CONNECT
  138. static esp_ip4_addr_t s_ip_addr;
  139. static void on_got_ip(void *arg, esp_event_base_t event_base,
  140. int32_t event_id, void *event_data)
  141. {
  142. ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
  143. if (!is_our_netif(TAG, event->esp_netif)) {
  144. ESP_LOGW(TAG, "Got IPv4 from another interface \"%s\": ignored", esp_netif_get_desc(event->esp_netif));
  145. return;
  146. }
  147. ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
  148. memcpy(&s_ip_addr, &event->ip_info.ip, sizeof(s_ip_addr));
  149. xSemaphoreGive(s_semph_get_ip_addrs);
  150. }
  151. #endif
  152. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  153. static void on_got_ipv6(void *arg, esp_event_base_t event_base,
  154. int32_t event_id, void *event_data)
  155. {
  156. ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
  157. if (!is_our_netif(TAG, event->esp_netif)) {
  158. ESP_LOGW(TAG, "Got IPv6 from another netif: ignored");
  159. return;
  160. }
  161. esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip);
  162. ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif),
  163. IPV62STR(event->ip6_info.ip), s_ipv6_addr_types[ipv6_type]);
  164. if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) {
  165. memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr));
  166. xSemaphoreGive(s_semph_get_ip_addrs);
  167. }
  168. }
  169. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  170. esp_err_t example_connect(void)
  171. {
  172. #if EXAMPLE_DO_CONNECT
  173. if (s_semph_get_ip_addrs != NULL) {
  174. return ESP_ERR_INVALID_STATE;
  175. }
  176. #endif
  177. start();
  178. ESP_ERROR_CHECK(esp_register_shutdown_handler(&stop));
  179. ESP_LOGI(TAG, "Waiting for IP(s)");
  180. for (int i = 0; i < NR_OF_IP_ADDRESSES_TO_WAIT_FOR; ++i) {
  181. xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY);
  182. }
  183. // iterate over active interfaces, and print out IPs of "our" netifs
  184. esp_netif_t *netif = NULL;
  185. esp_netif_ip_info_t ip;
  186. for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) {
  187. netif = esp_netif_next(netif);
  188. if (is_our_netif(TAG, netif)) {
  189. ESP_LOGI(TAG, "Connected to %s", esp_netif_get_desc(netif));
  190. ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip));
  191. ESP_LOGI(TAG, "- IPv4 address: " IPSTR, IP2STR(&ip.ip));
  192. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  193. esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF];
  194. int ip6_addrs = esp_netif_get_all_ip6(netif, ip6);
  195. for (int j = 0; j < ip6_addrs; ++j) {
  196. esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j]));
  197. ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(ip6[j]), s_ipv6_addr_types[ipv6_type]);
  198. }
  199. #endif
  200. }
  201. }
  202. return ESP_OK;
  203. }
  204. esp_err_t example_disconnect(void)
  205. {
  206. if (s_semph_get_ip_addrs == NULL) {
  207. return ESP_ERR_INVALID_STATE;
  208. }
  209. vSemaphoreDelete(s_semph_get_ip_addrs);
  210. s_semph_get_ip_addrs = NULL;
  211. stop();
  212. ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&stop));
  213. return ESP_OK;
  214. }
  215. #ifdef CONFIG_EXAMPLE_CONNECT_WIFI
  216. static void on_wifi_disconnect(void *arg, esp_event_base_t event_base,
  217. int32_t event_id, void *event_data)
  218. {
  219. ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect...");
  220. esp_err_t err = esp_wifi_connect();
  221. if (err == ESP_ERR_WIFI_NOT_STARTED) {
  222. return;
  223. }
  224. ESP_ERROR_CHECK(err);
  225. }
  226. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  227. static void on_wifi_connect(void *esp_netif, esp_event_base_t event_base,
  228. int32_t event_id, void *event_data)
  229. {
  230. esp_netif_create_ip6_linklocal(esp_netif);
  231. }
  232. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  233. static esp_netif_t *wifi_start(void)
  234. {
  235. char *desc;
  236. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  237. ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  238. esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA();
  239. // Prefix the interface description with the module TAG
  240. // Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask)
  241. asprintf(&desc, "%s: %s", TAG, esp_netif_config.if_desc);
  242. esp_netif_config.if_desc = desc;
  243. esp_netif_config.route_prio = 128;
  244. esp_netif_t *netif = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config);
  245. free(desc);
  246. esp_wifi_set_default_wifi_sta_handlers();
  247. ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL));
  248. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL));
  249. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  250. ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, netif));
  251. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
  252. #endif
  253. ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
  254. wifi_config_t wifi_config = {
  255. .sta = {
  256. .ssid = CONFIG_EXAMPLE_WIFI_SSID,
  257. .password = CONFIG_EXAMPLE_WIFI_PASSWORD,
  258. .scan_method = EXAMPLE_WIFI_SCAN_METHOD,
  259. .sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD,
  260. .threshold.rssi = CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD,
  261. .threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD,
  262. },
  263. };
  264. ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
  265. ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
  266. ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
  267. ESP_ERROR_CHECK(esp_wifi_start());
  268. esp_wifi_connect();
  269. return netif;
  270. }
  271. static void wifi_stop(void)
  272. {
  273. esp_netif_t *wifi_netif = get_example_netif_from_desc("sta");
  274. ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect));
  275. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip));
  276. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  277. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
  278. ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect));
  279. #endif
  280. esp_err_t err = esp_wifi_stop();
  281. if (err == ESP_ERR_WIFI_NOT_INIT) {
  282. return;
  283. }
  284. ESP_ERROR_CHECK(err);
  285. ESP_ERROR_CHECK(esp_wifi_deinit());
  286. ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(wifi_netif));
  287. esp_netif_destroy(wifi_netif);
  288. s_example_esp_netif = NULL;
  289. }
  290. #endif // CONFIG_EXAMPLE_CONNECT_WIFI
  291. #ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
  292. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  293. /** Event handler for Ethernet events */
  294. static void on_eth_event(void *esp_netif, esp_event_base_t event_base,
  295. int32_t event_id, void *event_data)
  296. {
  297. switch (event_id) {
  298. case ETHERNET_EVENT_CONNECTED:
  299. ESP_LOGI(TAG, "Ethernet Link Up");
  300. ESP_ERROR_CHECK(esp_netif_create_ip6_linklocal(esp_netif));
  301. break;
  302. default:
  303. break;
  304. }
  305. }
  306. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  307. static esp_eth_handle_t s_eth_handle = NULL;
  308. static esp_eth_mac_t *s_mac = NULL;
  309. static esp_eth_phy_t *s_phy = NULL;
  310. static esp_eth_netif_glue_handle_t s_eth_glue = NULL;
  311. static esp_netif_t *eth_start(void)
  312. {
  313. char *desc;
  314. esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
  315. // Prefix the interface description with the module TAG
  316. // Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask)
  317. asprintf(&desc, "%s: %s", TAG, esp_netif_config.if_desc);
  318. esp_netif_config.if_desc = desc;
  319. esp_netif_config.route_prio = 64;
  320. esp_netif_config_t netif_config = {
  321. .base = &esp_netif_config,
  322. .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
  323. };
  324. esp_netif_t *netif = esp_netif_new(&netif_config);
  325. assert(netif);
  326. free(desc);
  327. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  328. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  329. phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR;
  330. phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO;
  331. #if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
  332. mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
  333. mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
  334. s_mac = esp_eth_mac_new_esp32(&mac_config);
  335. #if CONFIG_EXAMPLE_ETH_PHY_IP101
  336. s_phy = esp_eth_phy_new_ip101(&phy_config);
  337. #elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
  338. s_phy = esp_eth_phy_new_rtl8201(&phy_config);
  339. #elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
  340. s_phy = esp_eth_phy_new_lan87xx(&phy_config);
  341. #elif CONFIG_EXAMPLE_ETH_PHY_DP83848
  342. s_phy = esp_eth_phy_new_dp83848(&phy_config);
  343. #endif
  344. #elif CONFIG_EXAMPLE_USE_SPI_ETHERNET
  345. gpio_install_isr_service(0);
  346. spi_device_handle_t spi_handle = NULL;
  347. spi_bus_config_t buscfg = {
  348. .miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
  349. .mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
  350. .sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
  351. .quadwp_io_num = -1,
  352. .quadhd_io_num = -1,
  353. };
  354. ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1));
  355. #if CONFIG_EXAMPLE_USE_DM9051
  356. spi_device_interface_config_t devcfg = {
  357. .command_bits = 1,
  358. .address_bits = 7,
  359. .mode = 0,
  360. .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
  361. .spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
  362. .queue_size = 20
  363. };
  364. ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
  365. /* dm9051 ethernet driver is based on spi driver */
  366. eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
  367. dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
  368. s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
  369. s_phy = esp_eth_phy_new_dm9051(&phy_config);
  370. #elif CONFIG_EXAMPLE_USE_W5500
  371. spi_device_interface_config_t devcfg = {
  372. .command_bits = 16, // Actually it's the address phase in W5500 SPI frame
  373. .address_bits = 8, // Actually it's the control phase in W5500 SPI frame
  374. .mode = 0,
  375. .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
  376. .spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
  377. .queue_size = 20
  378. };
  379. ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
  380. /* w5500 ethernet driver is based on spi driver */
  381. eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
  382. w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
  383. s_mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
  384. s_phy = esp_eth_phy_new_w5500(&phy_config);
  385. #endif
  386. #elif CONFIG_EXAMPLE_USE_OPENETH
  387. phy_config.autonego_timeout_ms = 100;
  388. s_mac = esp_eth_mac_new_openeth(&mac_config);
  389. s_phy = esp_eth_phy_new_dp83848(&phy_config);
  390. #endif
  391. // Install Ethernet driver
  392. esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy);
  393. ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
  394. #if !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
  395. /* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually.
  396. 02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control.
  397. */
  398. ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
  399. 0x02, 0x00, 0x00, 0x12, 0x34, 0x56
  400. }));
  401. #endif
  402. // combine driver with netif
  403. s_eth_glue = esp_eth_new_netif_glue(s_eth_handle);
  404. esp_netif_attach(netif, s_eth_glue);
  405. // Register user defined event handers
  406. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip, NULL));
  407. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  408. ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif));
  409. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
  410. #endif
  411. esp_eth_start(s_eth_handle);
  412. return netif;
  413. }
  414. static void eth_stop(void)
  415. {
  416. esp_netif_t *eth_netif = get_example_netif_from_desc("eth");
  417. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip));
  418. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  419. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
  420. ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event));
  421. #endif
  422. ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle));
  423. ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue));
  424. ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle));
  425. ESP_ERROR_CHECK(s_phy->del(s_phy));
  426. ESP_ERROR_CHECK(s_mac->del(s_mac));
  427. esp_netif_destroy(eth_netif);
  428. s_example_esp_netif = NULL;
  429. }
  430. #endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
  431. esp_netif_t *get_example_netif(void)
  432. {
  433. return s_example_esp_netif;
  434. }
  435. esp_netif_t *get_example_netif_from_desc(const char *desc)
  436. {
  437. esp_netif_t *netif = NULL;
  438. char *expected_desc;
  439. asprintf(&expected_desc, "%s: %s", TAG, desc);
  440. while ((netif = esp_netif_next(netif)) != NULL) {
  441. if (strcmp(esp_netif_get_desc(netif), expected_desc) == 0) {
  442. free(expected_desc);
  443. return netif;
  444. }
  445. }
  446. free(expected_desc);
  447. return netif;
  448. }