connect.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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_eth.h"
  13. #include "esp_log.h"
  14. #include "tcpip_adapter.h"
  15. #include "freertos/FreeRTOS.h"
  16. #include "freertos/task.h"
  17. #include "freertos/event_groups.h"
  18. #include "lwip/err.h"
  19. #include "lwip/sys.h"
  20. #define GOT_IPV4_BIT BIT(0)
  21. #define GOT_IPV6_BIT BIT(1)
  22. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  23. #define CONNECTED_BITS (GOT_IPV4_BIT | GOT_IPV6_BIT)
  24. #else
  25. #define CONNECTED_BITS (GOT_IPV4_BIT)
  26. #endif
  27. static EventGroupHandle_t s_connect_event_group;
  28. static ip4_addr_t s_ip_addr;
  29. static const char* s_connection_name;
  30. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  31. static ip6_addr_t s_ipv6_addr;
  32. #endif
  33. static const char *TAG = "example_connect";
  34. /* set up connection, Wi-Fi or Ethernet */
  35. static void start();
  36. /* tear down connection, release resources */
  37. static void stop();
  38. static void on_got_ip(void* arg, esp_event_base_t event_base,
  39. int32_t event_id, void* event_data)
  40. {
  41. ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
  42. memcpy(&s_ip_addr, &event->ip_info.ip, sizeof(s_ip_addr));
  43. xEventGroupSetBits(s_connect_event_group, GOT_IPV4_BIT);
  44. }
  45. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  46. static void on_got_ipv6(void* arg, esp_event_base_t event_base,
  47. int32_t event_id, void* event_data)
  48. {
  49. ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data;
  50. memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr));
  51. xEventGroupSetBits(s_connect_event_group, GOT_IPV6_BIT);
  52. }
  53. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  54. esp_err_t example_connect()
  55. {
  56. if (s_connect_event_group != NULL) {
  57. return ESP_ERR_INVALID_STATE;
  58. }
  59. s_connect_event_group = xEventGroupCreate();
  60. start();
  61. xEventGroupWaitBits(s_connect_event_group, CONNECTED_BITS, true, true, portMAX_DELAY);
  62. ESP_LOGI(TAG, "Connected to %s", s_connection_name);
  63. ESP_LOGI(TAG, "IPv4 address: " IPSTR, IP2STR(&s_ip_addr));
  64. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  65. ESP_LOGI(TAG, "IPv6 address: " IPV6STR, IPV62STR(s_ipv6_addr));
  66. #endif
  67. return ESP_OK;
  68. }
  69. esp_err_t example_disconnect()
  70. {
  71. if (s_connect_event_group == NULL) {
  72. return ESP_ERR_INVALID_STATE;
  73. }
  74. vEventGroupDelete(s_connect_event_group);
  75. s_connect_event_group = NULL;
  76. stop();
  77. ESP_LOGI(TAG, "Disconnected from %s", s_connection_name);
  78. s_connection_name = NULL;
  79. return ESP_OK;
  80. }
  81. #ifdef CONFIG_EXAMPLE_CONNECT_WIFI
  82. static void on_wifi_disconnect(void* arg, esp_event_base_t event_base,
  83. int32_t event_id, void* event_data)
  84. {
  85. ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect...");
  86. ESP_ERROR_CHECK( esp_wifi_connect() );
  87. }
  88. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  89. static void on_wifi_connect(void* arg, esp_event_base_t event_base,
  90. int32_t event_id, void* event_data)
  91. {
  92. tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
  93. }
  94. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  95. static void start()
  96. {
  97. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  98. ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  99. ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL));
  100. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL));
  101. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  102. ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, NULL));
  103. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
  104. #endif
  105. ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
  106. wifi_config_t wifi_config = {
  107. .sta = {
  108. .ssid = CONFIG_EXAMPLE_WIFI_SSID,
  109. .password = CONFIG_EXAMPLE_WIFI_PASSWORD,
  110. },
  111. };
  112. ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
  113. ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
  114. ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
  115. ESP_ERROR_CHECK(esp_wifi_start());
  116. ESP_ERROR_CHECK(esp_wifi_connect());
  117. s_connection_name = CONFIG_EXAMPLE_WIFI_SSID;
  118. }
  119. static void stop()
  120. {
  121. ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect));
  122. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip));
  123. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  124. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
  125. ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect));
  126. #endif
  127. ESP_ERROR_CHECK(esp_wifi_stop());
  128. ESP_ERROR_CHECK(esp_wifi_deinit());
  129. }
  130. #endif // CONFIG_EXAMPLE_CONNECT_WIFI
  131. #ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
  132. #include "driver/gpio.h"
  133. #ifdef CONFIG_PHY_LAN8720
  134. #include "eth_phy/phy_lan8720.h"
  135. #define DEFAULT_ETHERNET_PHY_CONFIG phy_lan8720_default_ethernet_config
  136. #endif
  137. #ifdef CONFIG_PHY_TLK110
  138. #include "eth_phy/phy_tlk110.h"
  139. #define DEFAULT_ETHERNET_PHY_CONFIG phy_tlk110_default_ethernet_config
  140. #elif CONFIG_PHY_IP101
  141. #include "eth_phy/phy_ip101.h"
  142. #define DEFAULT_ETHERNET_PHY_CONFIG phy_ip101_default_ethernet_config
  143. #endif
  144. #define PIN_PHY_POWER CONFIG_PHY_POWER_PIN
  145. #define PIN_SMI_MDC CONFIG_PHY_SMI_MDC_PIN
  146. #define PIN_SMI_MDIO CONFIG_PHY_SMI_MDIO_PIN
  147. #ifdef CONFIG_PHY_USE_POWER_PIN
  148. /**
  149. * @brief re-define power enable func for phy
  150. *
  151. * @param enable true to enable, false to disable
  152. *
  153. * @note This function replaces the default PHY power on/off function.
  154. * If this GPIO is not connected on your device (and PHY is always powered),
  155. * you can use the default PHY-specific power on/off function.
  156. */
  157. static void phy_device_power_enable_via_gpio(bool enable)
  158. {
  159. assert(DEFAULT_ETHERNET_PHY_CONFIG.phy_power_enable);
  160. if (!enable) {
  161. DEFAULT_ETHERNET_PHY_CONFIG.phy_power_enable(false);
  162. }
  163. gpio_pad_select_gpio(PIN_PHY_POWER);
  164. gpio_set_direction(PIN_PHY_POWER, GPIO_MODE_OUTPUT);
  165. if (enable == true) {
  166. gpio_set_level(PIN_PHY_POWER, 1);
  167. ESP_LOGI(TAG, "Power On Ethernet PHY");
  168. } else {
  169. gpio_set_level(PIN_PHY_POWER, 0);
  170. ESP_LOGI(TAG, "Power Off Ethernet PHY");
  171. }
  172. vTaskDelay(1); // Allow the power up/down to take effect, min 300us
  173. if (enable) {
  174. /* call the default PHY-specific power on function */
  175. DEFAULT_ETHERNET_PHY_CONFIG.phy_power_enable(true);
  176. }
  177. }
  178. #endif
  179. /**
  180. * @brief gpio specific init
  181. *
  182. * @note RMII data pins are fixed in esp32:
  183. * TXD0 <=> GPIO19
  184. * TXD1 <=> GPIO22
  185. * TX_EN <=> GPIO21
  186. * RXD0 <=> GPIO25
  187. * RXD1 <=> GPIO26
  188. * CLK <=> GPIO0
  189. *
  190. */
  191. static void eth_gpio_config_rmii(void)
  192. {
  193. phy_rmii_configure_data_interface_pins();
  194. phy_rmii_smi_configure_pins(PIN_SMI_MDC, PIN_SMI_MDIO);
  195. }
  196. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  197. /** Event handler for Ethernet events */
  198. static void on_eth_event(void* arg, esp_event_base_t event_base,
  199. int32_t event_id, void* event_data)
  200. {
  201. switch (event_id) {
  202. case ETHERNET_EVENT_CONNECTED:
  203. ESP_LOGI(TAG, "Ethernet Link Up");
  204. tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH);
  205. break;
  206. default:
  207. break;
  208. }
  209. }
  210. #endif // CONFIG_EXAMPLE_CONNECT_IPV6
  211. static void start()
  212. {
  213. eth_config_t config = DEFAULT_ETHERNET_PHY_CONFIG;
  214. config.phy_addr = CONFIG_PHY_ADDRESS;
  215. config.gpio_config = eth_gpio_config_rmii;
  216. config.tcpip_input = tcpip_adapter_eth_input;
  217. config.clock_mode = CONFIG_PHY_CLOCK_MODE;
  218. #ifdef CONFIG_PHY_USE_POWER_PIN
  219. /* Replace the default 'power enable' function with an example-specific one
  220. that toggles a power GPIO. */
  221. config.phy_power_enable = phy_device_power_enable_via_gpio;
  222. #endif
  223. ESP_ERROR_CHECK(esp_eth_init(&config));
  224. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip, NULL));
  225. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  226. ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, NULL));
  227. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
  228. #endif
  229. ESP_ERROR_CHECK(esp_eth_enable());
  230. s_connection_name = "Ethernet";
  231. }
  232. static void stop()
  233. {
  234. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip));
  235. #ifdef CONFIG_EXAMPLE_CONNECT_IPV6
  236. ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
  237. ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event));
  238. #endif
  239. ESP_ERROR_CHECK(esp_eth_disable());
  240. ESP_ERROR_CHECK(esp_eth_deinit());
  241. }
  242. #endif // CONFIG_EXAMPLE_CONNECT_ETHERNET