connect.c 9.0 KB

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