| 384 | } |
| 385 | |
| 386 | esp_err_t initEthernet(xsMachine *the) |
| 387 | { |
| 388 | uint8_t macaddr[6]; |
| 389 | esp_err_t err = ESP_OK; |
| 390 | esp_eth_mac_t *mac; |
| 391 | esp_eth_phy_t *phy; |
| 392 | esp_eth_handle_t eth_handle; |
| 393 | |
| 394 | ESP_LOGI(TAG, LOG_FMT("Initializing Ethernet")); |
| 395 | |
| 396 | if (gEthernetState > 0) return err; |
| 397 | |
| 398 | // Initialize netif and event loop first (required before creating netif objects) |
| 399 | ESP_ERROR_CHECK(esp_netif_init()); |
| 400 | err = esp_event_loop_create_default(); |
| 401 | if (ESP_ERR_INVALID_STATE != err) // ESP_ERR_INVALID_STATE indicates the default event loop has already been created |
| 402 | ESP_ERROR_CHECK(err); |
| 403 | |
| 404 | esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH(); |
| 405 | gNetif = esp_netif_new(&netif_cfg); |
| 406 | |
| 407 | #ifdef MODDEF_ETHERNET_POWER_PIN |
| 408 | // Turn ethernet phy on. This is needed if you control power to the Ethernet board. |
| 409 | // Perform a hard reset by power cycling |
| 410 | ESP_LOGI(TAG, LOG_FMT("Applying Power using GPIO Pin=%d"), MODDEF_ETHERNET_POWER_PIN); |
| 411 | gpio_set_direction(MODDEF_ETHERNET_POWER_PIN, GPIO_MODE_OUTPUT); |
| 412 | gpio_set_level(MODDEF_ETHERNET_POWER_PIN, 0); // First Power off for 100ms to ensure we turn it back on |
| 413 | vTaskDelay(pdMS_TO_TICKS(100)); // Hold in reset/off |
| 414 | gpio_set_level(MODDEF_ETHERNET_POWER_PIN, 1); // Power on |
| 415 | vTaskDelay(pdMS_TO_TICKS(200)); // LAN8720A needs ~200ms to stabilize after power-on |
| 416 | if (MODDEF_ETHERNET_DEBUG) ESP_LOGI(TAG, LOG_FMT("Power applied to Ethernet")); |
| 417 | #endif |
| 418 | |
| 419 | #ifdef MODDEF_ETHERNET_INTERNAL_PHY_GPIO0_CLOCK_INPUT |
| 420 | // Configure GPIO0 as input to prevent conflict with external 50MHz oscillator (RMII_CLK) |
| 421 | // This is critical for WT32-ETH01 and similar boards with external clock source |
| 422 | gpio_reset_pin(GPIO_NUM_0); |
| 423 | gpio_set_direction(GPIO_NUM_0, GPIO_MODE_INPUT); |
| 424 | gpio_set_pull_mode(GPIO_NUM_0, GPIO_FLOATING); |
| 425 | vTaskDelay(pdMS_TO_TICKS(50)); // Allow clock to stabilize |
| 426 | ESP_LOGI(TAG, LOG_FMT("Configured GPIO0 as input for external RMII clock")); |
| 427 | #endif // #ifdef MODDEF_ETHERNET_INTERNAL_PHY_GPIO0_CLOCK_INPUT |
| 428 | #ifdef MODDEF_ETHERNET_INTERNAL_PHY_ADDRESS |
| 429 | // Ensure MDIO has pull-up (open-drain bidirectional bus) |
| 430 | gpio_set_pull_mode(MODDEF_ETHERNET_INTERNAL_MAC_MDIO, GPIO_PULLUP_ONLY); |
| 431 | if (MODDEF_ETHERNET_DEBUG) ESP_LOGI(TAG, LOG_FMT("Configured MDIO (GPIO%d) with pull-up"), MODDEF_ETHERNET_INTERNAL_MAC_MDIO); |
| 432 | |
| 433 | eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); |
| 434 | eth_esp32_emac_config_t esp32_mac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); |
| 435 | esp32_mac_config.smi_gpio.mdc_num = MODDEF_ETHERNET_INTERNAL_MAC_MDC; |
| 436 | esp32_mac_config.smi_gpio.mdio_num = MODDEF_ETHERNET_INTERNAL_MAC_MDIO; |
| 437 | // Explicit clock configuration (uncomment if sdkconfig settings aren't working) |
| 438 | // esp32_mac_config.clock_config.rmii.clock_mode = EMAC_CLK_EXT_IN; |
| 439 | // esp32_mac_config.clock_config.rmii.clock_gpio = EMAC_CLK_IN_GPIO; |
| 440 | // ESP_LOGI(TAG, LOG_FMT("Initialize Ethernet ESP32 MAC with MDC=%d, MDIO=%d, external clock on GPIO0"), |
| 441 | if (MODDEF_ETHERNET_DEBUG) ESP_LOGI(TAG, LOG_FMT("Initialize Ethernet ESP32 MAC with MDC=%d and MDIO=%d"), |
| 442 | MODDEF_ETHERNET_INTERNAL_MAC_MDC, MODDEF_ETHERNET_INTERNAL_MAC_MDIO); |
| 443 | mac = esp_eth_mac_new_esp32(&esp32_mac_config, &mac_config); |
no test coverage detected