connect.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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. #endif
  16. #include "esp_log.h"
  17. #include "esp_netif.h"
  18. #include "driver/gpio.h"
  19. #include "freertos/FreeRTOS.h"
  20. #include "freertos/task.h"
  21. #include "freertos/event_groups.h"
  22. #include "lwip/err.h"
  23. #include "lwip/sys.h"
  24. #define GOT_IPV4_BIT BIT(0)
  25. #define GOT_IPV6_BIT BIT(1)
  26. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  27. #define CONNECTED_BITS (GOT_IPV4_BIT | GOT_IPV6_BIT)
  28. #if defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK)
  29. #define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_LINK_LOCAL
  30. #elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL)
  31. #define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_GLOBAL
  32. #elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL)
  33. #define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_SITE_LOCAL
  34. #elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL)
  35. #define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_UNIQUE_LOCAL
  36. #endif // if-elif CONFIG_EXAMPLE_CONNECT_IPV6_PREF_...
  37. #else
  38. #define CONNECTED_BITS (GOT_IPV4_BIT)
  39. #endif
  40. static EventGroupHandle_t s_connect_event_group;
  41. static esp_ip4_addr_t s_ip_addr;
  42. static const char *s_connection_name;
  43. static esp_netif_t *s_example_esp_netif = NULL;
  44. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  45. static esp_ip6_addr_t s_ipv6_addr;
  46. /* types of ipv6 addresses to be displayed on ipv6 events */
  47. static const char *s_ipv6_addr_types[] = {
  48. "ESP_IP6_ADDR_IS_UNKNOWN",
  49. "ESP_IP6_ADDR_IS_GLOBAL",
  50. "ESP_IP6_ADDR_IS_LINK_LOCAL",
  51. "ESP_IP6_ADDR_IS_SITE_LOCAL",
  52. "ESP_IP6_ADDR_IS_UNIQUE_LOCAL",
  53. "ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6"
  54. };
  55. #endif
  56. static const char *TAG = "example_connect";
  57. /* set up connection, Wi-Fi or Ethernet */
  58. static void start(void);
  59. /* tear down connection, release resources */
  60. static void stop(void);
  61. static void on_got_ip(void *arg, esp_event_base_t event_base,
  62. int32_t event_id, void *event_data)
  63. {
  64. ESP_LOGI(TAG, "Got IP event!");
  65. ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
  66. memcpy(&s_ip_addr, &event->ip_info.ip, sizeof(s_ip_addr));
  67. xEventGroupSetBits(s_connect_event_group, GOT_IPV4_BIT);
  68. }
  69. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  70. static void on_got_ipv6(void *arg, esp_event_base_t event_base,
  71. int32_t event_id, void *event_data)
  72. {
  73. ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
  74. if (event->esp_netif != s_example_esp_netif) {
  75. ESP_LOGD(TAG, "Got IPv6 from another netif: ignored");
  76. return;
  77. }
  78. esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip);
  79. ESP_LOGI(TAG, "Got IPv6 address: " IPV6STR ", type: %s", IPV62STR(event->ip6_info.ip), s_ipv6_addr_types[ipv6_type]);
  80. if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) {
  81. memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr));
  82. xEventGroupSetBits(s_connect_event_group, GOT_IPV6_BIT);
  83. }
  84. }
  85. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  86. esp_err_t example_connect(void)
  87. {
  88. if (s_connect_event_group != NULL) {
  89. return ESP_ERR_INVALID_STATE;
  90. }
  91. s_connect_event_group = xEventGroupCreate();
  92. start();
  93. ESP_ERROR_CHECK(esp_register_shutdown_handler(&stop));
  94. ESP_LOGI(TAG, "Waiting for IP");
  95. xEventGroupWaitBits(s_connect_event_group, CONNECTED_BITS, true, true, portMAX_DELAY);
  96. ESP_LOGI(TAG, "Connected to %s", s_connection_name);
  97. ESP_LOGI(TAG, "IPv4 address: " IPSTR, IP2STR(&s_ip_addr));
  98. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  99. ESP_LOGI(TAG, "IPv6 address: " IPV6STR, IPV62STR(s_ipv6_addr));
  100. #endif
  101. return ESP_OK;
  102. }
  103. esp_err_t example_disconnect(void)
  104. {
  105. if (s_connect_event_group == NULL) {
  106. return ESP_ERR_INVALID_STATE;
  107. }
  108. vEventGroupDelete(s_connect_event_group);
  109. s_connect_event_group = NULL;
  110. stop();
  111. ESP_LOGI(TAG, "Disconnected from %s", s_connection_name);
  112. s_connection_name = NULL;
  113. return ESP_OK;
  114. }
  115. #ifdef CONFIG_EXAMPLE_CONNECT_WIFI
  116. static void on_wifi_disconnect(void *arg, esp_event_base_t event_base,
  117. int32_t event_id, void *event_data)
  118. {
  119. ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect...");
  120. esp_err_t err = esp_wifi_connect();
  121. if (err == ESP_ERR_WIFI_NOT_STARTED) {
  122. return;
  123. }
  124. ESP_ERROR_CHECK(err);
  125. }
  126. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  127. static void on_wifi_connect(void *esp_netif, esp_event_base_t event_base,
  128. int32_t event_id, void *event_data)
  129. {
  130. esp_netif_create_ip6_linklocal(esp_netif);
  131. }
  132. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  133. static void start(void)
  134. {
  135. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  136. ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  137. esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_WIFI_STA();
  138. esp_netif_t *netif = esp_netif_new(&netif_config);
  139. assert(netif);
  140. esp_netif_attach_wifi_station(netif);
  141. esp_wifi_set_default_wifi_sta_handlers();
  142. s_example_esp_netif = netif;
  143. ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL));
  144. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL));
  145. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  146. ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, netif));
  147. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
  148. #endif
  149. ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
  150. wifi_config_t wifi_config = {
  151. .sta = {
  152. .ssid = CONFIG_EXAMPLE_WIFI_SSID,
  153. .password = CONFIG_EXAMPLE_WIFI_PASSWORD,
  154. },
  155. };
  156. ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
  157. ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
  158. ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
  159. ESP_ERROR_CHECK(esp_wifi_start());
  160. ESP_ERROR_CHECK(esp_wifi_connect());
  161. s_connection_name = CONFIG_EXAMPLE_WIFI_SSID;
  162. }
  163. static void stop(void)
  164. {
  165. ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect));
  166. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip));
  167. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  168. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
  169. ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect));
  170. #endif
  171. esp_err_t err = esp_wifi_stop();
  172. if (err == ESP_ERR_WIFI_NOT_INIT) {
  173. return;
  174. }
  175. ESP_ERROR_CHECK(err);
  176. ESP_ERROR_CHECK(esp_wifi_deinit());
  177. ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(s_example_esp_netif));
  178. esp_netif_destroy(s_example_esp_netif);
  179. s_example_esp_netif = NULL;
  180. }
  181. #endif // CONFIG_EXAMPLE_CONNECT_WIFI
  182. #ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
  183. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  184. /** Event handler for Ethernet events */
  185. static void on_eth_event(void *esp_netif, esp_event_base_t event_base,
  186. int32_t event_id, void *event_data)
  187. {
  188. switch (event_id) {
  189. case ETHERNET_EVENT_CONNECTED:
  190. ESP_LOGI(TAG, "Ethernet Link Up");
  191. esp_netif_create_ip6_linklocal(esp_netif);
  192. break;
  193. default:
  194. break;
  195. }
  196. }
  197. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  198. static esp_eth_handle_t s_eth_handle = NULL;
  199. static esp_eth_mac_t *s_mac = NULL;
  200. static esp_eth_phy_t *s_phy = NULL;
  201. static void *s_eth_glue = NULL;
  202. static void start(void)
  203. {
  204. esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_ETH();
  205. esp_netif_t *netif = esp_netif_new(&netif_config);
  206. assert(netif);
  207. s_example_esp_netif = netif;
  208. // Set default handlers to process TCP/IP stuffs
  209. ESP_ERROR_CHECK(esp_eth_set_default_handlers(netif));
  210. // Register user defined event handers
  211. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip, NULL));
  212. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  213. ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif));
  214. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
  215. #endif
  216. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  217. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  218. phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR;
  219. phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO;
  220. #if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
  221. mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
  222. mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
  223. s_mac = esp_eth_mac_new_esp32(&mac_config);
  224. #if CONFIG_EXAMPLE_ETH_PHY_IP101
  225. s_phy = esp_eth_phy_new_ip101(&phy_config);
  226. #elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
  227. s_phy = esp_eth_phy_new_rtl8201(&phy_config);
  228. #elif CONFIG_EXAMPLE_ETH_PHY_LAN8720
  229. s_phy = esp_eth_phy_new_lan8720(&phy_config);
  230. #elif CONFIG_EXAMPLE_ETH_PHY_DP83848
  231. s_phy = esp_eth_phy_new_dp83848(&phy_config);
  232. #endif
  233. #elif CONFIG_EXAMPLE_USE_DM9051
  234. gpio_install_isr_service(0);
  235. spi_device_handle_t spi_handle = NULL;
  236. spi_bus_config_t buscfg = {
  237. .miso_io_num = CONFIG_EXAMPLE_DM9051_MISO_GPIO,
  238. .mosi_io_num = CONFIG_EXAMPLE_DM9051_MOSI_GPIO,
  239. .sclk_io_num = CONFIG_EXAMPLE_DM9051_SCLK_GPIO,
  240. .quadwp_io_num = -1,
  241. .quadhd_io_num = -1,
  242. };
  243. ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_DM9051_SPI_HOST, &buscfg, 1));
  244. spi_device_interface_config_t devcfg = {
  245. .command_bits = 1,
  246. .address_bits = 7,
  247. .mode = 0,
  248. .clock_speed_hz = CONFIG_EXAMPLE_DM9051_SPI_CLOCK_MHZ * 1000 * 1000,
  249. .spics_io_num = CONFIG_EXAMPLE_DM9051_CS_GPIO,
  250. .queue_size = 20
  251. };
  252. ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_DM9051_SPI_HOST, &devcfg, &spi_handle));
  253. /* dm9051 ethernet driver is based on spi driver */
  254. eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
  255. dm9051_config.int_gpio_num = CONFIG_EXAMPLE_DM9051_INT_GPIO;
  256. s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
  257. s_phy = esp_eth_phy_new_dm9051(&phy_config);
  258. #elif CONFIG_EXAMPLE_USE_OPENETH
  259. phy_config.autonego_timeout_ms = 100;
  260. s_mac = esp_eth_mac_new_openeth(&mac_config);
  261. s_phy = esp_eth_phy_new_dp83848(&phy_config);
  262. #endif
  263. // Install Ethernet driver
  264. esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy);
  265. ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
  266. // combine driver with netif
  267. s_eth_glue = esp_eth_new_netif_glue(s_eth_handle);
  268. esp_netif_attach(netif, s_eth_glue);
  269. esp_eth_start(s_eth_handle);
  270. s_connection_name = "Ethernet";
  271. }
  272. static void stop(void)
  273. {
  274. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip));
  275. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  276. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
  277. ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event));
  278. #endif
  279. ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle));
  280. ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue));
  281. ESP_ERROR_CHECK(esp_eth_clear_default_handlers(s_example_esp_netif));
  282. ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle));
  283. ESP_ERROR_CHECK(s_phy->del(s_phy));
  284. ESP_ERROR_CHECK(s_mac->del(s_mac));
  285. esp_netif_destroy(s_example_esp_netif);
  286. s_example_esp_netif = NULL;
  287. }
  288. #endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
  289. esp_netif_t *get_example_netif(void)
  290. {
  291. return s_example_esp_netif;
  292. }