RCM — ESP32 Room Controller
WT32-ETH01 firmware
Loading...
Searching...
No Matches
ethernet.c
Go to the documentation of this file.
1
13#include "ethernet.h"
14
15#include "driver/gpio.h"
16#include "esp_check.h"
17#include "esp_eth.h"
18#include "esp_event.h"
19#include "esp_log.h"
20#include "esp_netif.h"
21#include "freertos/FreeRTOS.h"
22#include "freertos/task.h"
23#include "mqtt_app.h"
24#include "web_server.h"
25
26static const char *TAG = "ethernet";
27
28/* --- Распиновка WT32-ETH01 V1.4 (PHY LAN8720A, интерфейс RMII) --- */
29
31#define ETH_PHY_ADDR 1
32
34#define ETH_MDC_GPIO 23
35
37#define ETH_MDIO_GPIO 18
38
40#define ETH_PHY_POWER_GPIO 16
41
43#define ETH_RMII_CLK_GPIO 0
44
46static esp_eth_handle_t s_eth_handle;
47
49static esp_netif_t *s_eth_netif;
50
52static esp_eth_netif_glue_handle_t s_eth_glue;
53
55static httpd_handle_t s_http_server;
56
65static void eth_event_handler(void *arg, esp_event_base_t event_base,
66 int32_t event_id, void *event_data)
67{
68 uint8_t mac[6];
69
70 switch (event_id) {
71 case ETHERNET_EVENT_CONNECTED:
72 /* Линк установлен — читаем и логируем MAC-адрес интерфейса */
73 esp_eth_ioctl(s_eth_handle, ETH_CMD_G_MAC_ADDR, mac);
74 ESP_LOGI(TAG, "Link up, MAC %02x:%02x:%02x:%02x:%02x:%02x",
75 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
76 break;
77
78 case ETHERNET_EVENT_DISCONNECTED:
79 /* Кабель отключён или линк потерян — останавливаем веб-сервер */
80 ESP_LOGI(TAG, "Link down");
82 if (s_http_server) {
84 s_http_server = NULL;
85 }
86 break;
87
88 default:
89 break;
90 }
91}
92
99static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
100 int32_t event_id, void *event_data)
101{
102 ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
103 const esp_netif_ip_info_t *ip = &event->ip_info;
104
105 ESP_LOGI(TAG, "IP: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
106 IP2STR(&ip->ip), IP2STR(&ip->netmask), IP2STR(&ip->gw));
107
108 if (s_http_server == NULL) {
109 ESP_ERROR_CHECK(web_server_start(&s_http_server));
110 }
111
112 ESP_ERROR_CHECK(mqtt_app_start());
113}
114
127static esp_err_t wt32_eth_driver_init(esp_eth_handle_t *eth_handle_out)
128{
129 ESP_RETURN_ON_FALSE(eth_handle_out, ESP_ERR_INVALID_ARG, TAG, "null handle");
130
131 /* Настройка GPIO питания PHY: выход, без подтяжек */
132 gpio_config_t pwr_conf = {
133 .pin_bit_mask = 1ULL << ETH_PHY_POWER_GPIO,
134 .mode = GPIO_MODE_OUTPUT,
135 .pull_up_en = GPIO_PULLUP_DISABLE,
136 .pull_down_en = GPIO_PULLDOWN_DISABLE,
137 .intr_type = GPIO_INTR_DISABLE,
138 };
139 ESP_RETURN_ON_ERROR(gpio_config(&pwr_conf), TAG, "PHY power GPIO config failed");
140 ESP_RETURN_ON_ERROR(gpio_set_level(ETH_PHY_POWER_GPIO, 1), TAG, "PHY power enable failed");
141
142 /* Задержка после включения питания — PHY должен выйти в рабочий режим */
143 vTaskDelay(pdMS_TO_TICKS(100));
144
145 eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
146 eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
147 phy_config.phy_addr = ETH_PHY_ADDR;
148 phy_config.reset_gpio_num = -1; /* Сброс PHY не через отдельный GPIO */
149
150 eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
151 esp32_emac_config.interface = EMAC_DATA_INTERFACE_RMII;
152 /* Такт RMII приходит с PHY на GPIO0 (режим внешнего clock) */
153 esp32_emac_config.clock_config.rmii.clock_mode = EMAC_CLK_EXT_IN;
154 esp32_emac_config.clock_config.rmii.clock_gpio = ETH_RMII_CLK_GPIO;
155 esp32_emac_config.smi_gpio.mdc_num = ETH_MDC_GPIO;
156 esp32_emac_config.smi_gpio.mdio_num = ETH_MDIO_GPIO;
157
158 esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
159 ESP_RETURN_ON_FALSE(mac, ESP_FAIL, TAG, "MAC init failed");
160
161 esp_eth_phy_t *phy = esp_eth_phy_new_generic(&phy_config);
162 if (phy == NULL) {
163 mac->del(mac);
164 ESP_RETURN_ON_FALSE(false, ESP_FAIL, TAG, "PHY init failed");
165 }
166
167 esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
168 ESP_RETURN_ON_ERROR(esp_eth_driver_install(&eth_config, eth_handle_out),
169 TAG, "driver install failed");
170
171 return ESP_OK;
172}
173
174esp_err_t ethernet_start(void)
175{
176 /* Базовая инициализация TCP/IP стека ESP-IDF */
177 ESP_RETURN_ON_ERROR(esp_netif_init(), TAG, "netif init failed");
178 ESP_RETURN_ON_ERROR(esp_event_loop_create_default(), TAG, "event loop failed");
179
180 ESP_RETURN_ON_ERROR(wt32_eth_driver_init(&s_eth_handle), TAG, "eth driver failed");
181
182 /* Создание сетевого интерфейса Ethernet с настройками по умолчанию (DHCP client) */
183 esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
184 s_eth_netif = esp_netif_new(&netif_cfg);
185 ESP_RETURN_ON_FALSE(s_eth_netif, ESP_ERR_NO_MEM, TAG, "netif create failed");
186
187 s_eth_glue = esp_eth_new_netif_glue(s_eth_handle);
188 ESP_RETURN_ON_ERROR(esp_netif_attach(s_eth_netif, s_eth_glue), TAG, "netif attach failed");
189
190 /* События линка Ethernet */
191 ESP_RETURN_ON_ERROR(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID,
192 &eth_event_handler, NULL),
193 TAG, "eth event register failed");
194 /* Событие «получен IP» для интерфейса Ethernet */
195 ESP_RETURN_ON_ERROR(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP,
196 &got_ip_event_handler, NULL),
197 TAG, "ip event register failed");
198
199 ESP_RETURN_ON_ERROR(esp_eth_start(s_eth_handle), TAG, "eth start failed");
200 ESP_LOGI(TAG, "Ethernet started, waiting for link and DHCP...");
201
202 return ESP_OK;
203}
static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
Обработчик получения IP-адреса по DHCP (или статической конфигурации).
Definition ethernet.c:99
static esp_eth_handle_t s_eth_handle
Дескриптор драйвера Ethernet (MAC + PHY)
Definition ethernet.c:46
#define ETH_PHY_POWER_GPIO
GPIO включения питания PHY (активный уровень — высокий)
Definition ethernet.c:40
static esp_err_t wt32_eth_driver_init(esp_eth_handle_t *eth_handle_out)
Инициализация драйвера Ethernet под конкретную плату WT32-ETH01.
Definition ethernet.c:127
esp_err_t ethernet_start(void)
Инициализирует и запускает Ethernet на плате WT32-ETH01.
Definition ethernet.c:174
static const char * TAG
Definition ethernet.c:26
#define ETH_RMII_CLK_GPIO
GPIO внешнего тактового сигнала RMII (50 МГц от PHY на GPIO0)
Definition ethernet.c:43
#define ETH_PHY_ADDR
Адрес PHY на шине SMI (MDC/MDIO), для LAN8720 на этой плате — 1.
Definition ethernet.c:31
static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
Обработчик событий Ethernet (линк, отключение и т.
Definition ethernet.c:65
#define ETH_MDC_GPIO
GPIO линии MDC (Management Data Clock) для SMI.
Definition ethernet.c:34
static httpd_handle_t s_http_server
Дескриптор HTTP-сервера; NULL, если сервер не запущен
Definition ethernet.c:55
#define ETH_MDIO_GPIO
GPIO линии MDIO (Management Data I/O) для SMI.
Definition ethernet.c:37
static esp_eth_netif_glue_handle_t s_eth_glue
Связка между esp_eth и esp_netif.
Definition ethernet.c:52
static esp_netif_t * s_eth_netif
Сетевой интерфейс LwIP для Ethernet.
Definition ethernet.c:49
Публичный интерфейс модуля Ethernet для WT32-ETH01.
esp_err_t mqtt_app_start(void)
Запускает MQTT-клиент и подключается к брокеру.
Definition mqtt_app.c:92
esp_err_t mqtt_app_stop(void)
Останавливает MQTT-клиент и освобождает ресурсы.
Definition mqtt_app.c:123
Публичный интерфейс MQTT-клиента.
esp_err_t web_server_stop(httpd_handle_t server)
Останавливает HTTP-сервер и освобождает ресурсы.
Definition web_server.c:148
esp_err_t web_server_start(httpd_handle_t *server_out)
Запускает HTTP-сервер на порту по умолчанию (80).
Definition web_server.c:130
Публичный интерфейс встроенного HTTP-сервера.