Merge branch 'feat/eth_gpio' into 'master'

feat(esp_eth): new gpio init strategy

Closes IDF-11128

See merge request espressif/esp-idf!35827
This commit is contained in:
Ondrej Kosta
2025-01-22 20:20:07 +08:00
14 changed files with 129 additions and 86 deletions

View File

@@ -32,13 +32,13 @@ static esp_err_t emac_esp_gpio_matrix_init(gpio_num_t gpio_num, uint32_t signal_
ESP_LOGD(TAG, "%s skipping signal in_idx %" PRIu32 ", out_idx %" PRIu32, __func__, signal_in_idx, signal_out_idx);
return ESP_OK;
}
ESP_RETURN_ON_ERROR(gpio_set_direction(gpio_num, mode), TAG, "failed to set direction %i at GPIO #%i", mode, gpio_num);
switch(mode) {
case GPIO_MODE_INPUT:
ESP_RETURN_ON_FALSE(signal_in_idx != SIG_GPIO_OUT_IDX, ESP_ERR_NOT_SUPPORTED,
TAG, "requested periph signal cannot be connect via GPIO Matrix");
ESP_RETURN_ON_FALSE(esp_gpio_is_reserved(BIT64(gpio_num)) == false, ESP_ERR_INVALID_STATE,
TAG, "GPIO %i is reserved", gpio_num);
gpio_input_enable(gpio_num);
esp_rom_gpio_connect_in_signal(gpio_num, signal_in_idx, false);
break;
case GPIO_MODE_OUTPUT:
@@ -55,6 +55,7 @@ static esp_err_t emac_esp_gpio_matrix_init(gpio_num_t gpio_num, uint32_t signal_
TAG, "requested periph signal cannot be connect via GPIO Matrix");
ESP_RETURN_ON_FALSE((esp_gpio_reserve(BIT64(gpio_num)) & BIT64(gpio_num)) == 0, ESP_ERR_INVALID_STATE,
TAG, "GPIO %i is already reserved", gpio_num);
gpio_input_enable(gpio_num);
esp_rom_gpio_connect_out_signal(gpio_num, signal_out_idx, false, false);
esp_rom_gpio_connect_in_signal(gpio_num, signal_in_idx, false);
break;
@@ -67,7 +68,7 @@ static esp_err_t emac_esp_gpio_matrix_init(gpio_num_t gpio_num, uint32_t signal_
return ESP_OK;
}
static esp_err_t emac_esp_iomux_init(gpio_num_t gpio_num, const emac_iomux_info_t *iomux_info, bool is_input)
static esp_err_t emac_esp_iomux_init(gpio_num_t gpio_num, const emac_iomux_info_t *iomux_info, uint32_t signal_idx, bool is_input)
{
// silently skip undefined iomux functions (for example, ESP32 does not use MII COL_IN/CRS_IN)
if (iomux_info == NULL) {
@@ -81,16 +82,23 @@ static esp_err_t emac_esp_iomux_init(gpio_num_t gpio_num, const emac_iomux_info_
}
// loop over target iomux_info until reached end of list indicated by invalid GPIO num
while (iomux_info->gpio_num != GPIO_NUM_MAX) {
// if requested GPIO number can be IO muxed or select single pad that can be muxed on the target
// if requested GPIO number can be IO muxed or select the only pad that can be muxed on the target
if(gpio_num == iomux_info->gpio_num || gpio_num == GPIO_NUM_MAX) {
ESP_RETURN_ON_FALSE((esp_gpio_reserve(BIT64(iomux_info->gpio_num)) & BIT64(iomux_info->gpio_num)) == 0, ESP_ERR_INVALID_STATE,
TAG, "GPIO %i is already reserved", iomux_info->gpio_num);
s_emac_esp_used_gpio_mask |= BIT64(iomux_info->gpio_num);
ESP_RETURN_ON_ERROR(gpio_func_sel(iomux_info->gpio_num, iomux_info->func), TAG, "failed to set GPIO function at GPIO %i", iomux_info->gpio_num);
if (is_input) {
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[iomux_info->gpio_num]);
ESP_RETURN_ON_ERROR(gpio_func_sel(iomux_info->gpio_num, iomux_info->func), TAG, "failed to set GPIO function at GPIO %i", iomux_info->gpio_num);
// if the signal can be also connected via IO matrix, disconnect it (SIG_GPIO_OUT_IDX indicates no IO matrix)
if (signal_idx != SIG_GPIO_OUT_IDX) {
// enable input and disconnect from IO Matrix
gpio_iomux_in(iomux_info->gpio_num, signal_idx);
} else {
// just enable input
gpio_input_enable(iomux_info->gpio_num);
}
} else {
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[iomux_info->gpio_num]);
gpio_iomux_out(iomux_info->gpio_num, iomux_info->func, false);
}
ESP_RETURN_ON_ERROR(gpio_set_pull_mode(iomux_info->gpio_num, GPIO_FLOATING),
TAG, "failed to set pull mode at GPIO %i", iomux_info->gpio_num);
@@ -158,34 +166,34 @@ esp_err_t emac_esp_iomux_init_mii(const eth_mac_mii_gpio_config_t *mii_gpio)
{
ESP_RETURN_ON_FALSE(emac_mii_iomux_pins.clk_tx != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support MII IOMUX");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, tx_clk_num), emac_mii_iomux_pins.clk_tx, true),
TAG, "invalid TX_CLK GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, tx_en_num), emac_mii_iomux_pins.tx_en, false),
TAG, "invalid TX_EN GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd0_num), emac_mii_iomux_pins.txd0, false),
TAG, "invalid TXD0 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd1_num), emac_mii_iomux_pins.txd1, false),
TAG, "invalid TXD1 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd2_num), emac_mii_iomux_pins.txd2, false),
TAG, "invalid TXD2 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd3_num), emac_mii_iomux_pins.txd3, false),
TAG, "invalid TXD3 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rx_clk_num), emac_mii_iomux_pins.clk_rx, true),
TAG, "invalid RX_CLK GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rx_dv_num), emac_mii_iomux_pins.rx_dv, true),
TAG, "invalid RX_DV GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd0_num), emac_mii_iomux_pins.rxd0, true),
TAG, "invalid RXD0 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd1_num), emac_mii_iomux_pins.rxd1, true),
TAG, "invalid RXD1 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd2_num), emac_mii_iomux_pins.rxd2, true),
TAG, "invalid RXD2 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd3_num), emac_mii_iomux_pins.rxd3, true),
TAG, "invalid RXD3 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, col_in_num), emac_mii_iomux_pins.col_in, true),
TAG, "invalid COL_IN GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, crs_in_num), emac_mii_iomux_pins.crs_in, true),
TAG, "invalid CRS_IN GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, tx_clk_num), emac_mii_iomux_pins.clk_tx,
emac_io_idx.mii_tx_clk_i_idx, true), TAG, "invalid TX_CLK GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, tx_en_num), emac_mii_iomux_pins.tx_en,
emac_io_idx.mii_tx_en_o_idx, false), TAG, "invalid TX_EN GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd0_num), emac_mii_iomux_pins.txd0,
emac_io_idx.mii_txd0_o_idx, false), TAG, "invalid TXD0 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd1_num), emac_mii_iomux_pins.txd1,
emac_io_idx.mii_txd1_o_idx, false), TAG, "invalid TXD1 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd2_num), emac_mii_iomux_pins.txd2,
emac_io_idx.mii_txd2_o_idx, false), TAG, "invalid TXD2 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd3_num), emac_mii_iomux_pins.txd3,
emac_io_idx.mii_txd3_o_idx, false), TAG, "invalid TXD3 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rx_clk_num), emac_mii_iomux_pins.clk_rx,
emac_io_idx.mii_rx_clk_i_idx, true), TAG, "invalid RX_CLK GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rx_dv_num), emac_mii_iomux_pins.rx_dv,
emac_io_idx.mii_rx_dv_i_idx, true), TAG, "invalid RX_DV GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd0_num), emac_mii_iomux_pins.rxd0,
emac_io_idx.mii_rxd0_i_idx, true), TAG, "invalid RXD0 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd1_num), emac_mii_iomux_pins.rxd1,
emac_io_idx.mii_rxd1_i_idx, true), TAG, "invalid RXD1 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd2_num), emac_mii_iomux_pins.rxd2,
emac_io_idx.mii_rxd2_i_idx, true), TAG, "invalid RXD2 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd3_num), emac_mii_iomux_pins.rxd3,
emac_io_idx.mii_rxd3_i_idx, true), TAG, "invalid RXD3 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, col_in_num), emac_mii_iomux_pins.col_in,
emac_io_idx.mii_col_i_idx, true), TAG, "invalid COL_IN GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, crs_in_num), emac_mii_iomux_pins.crs_in,
emac_io_idx.mii_crs_i_idx, true), TAG, "invalid CRS_IN GPIO number");
return ESP_OK;
}
@@ -193,7 +201,8 @@ esp_err_t emac_esp_iomux_rmii_clk_input(int num)
{
ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.clki != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII CLKI IOMUX");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.clki, true), TAG, "invalid RMII CLK input GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.clki, emac_io_idx.rmii_refclk_i_idx, true),
TAG, "invalid RMII CLK input GPIO number");
return ESP_OK;
}
@@ -201,7 +210,8 @@ esp_err_t emac_esp_iomux_rmii_clk_ouput(int num)
{
ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.clko != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII CLKO IOMUX");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.clko, false), TAG, "invalid RMII CLK output GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.clko, emac_io_idx.rmii_refclk_o_idx, false),
TAG, "invalid RMII CLK output GPIO number");
return ESP_OK;
}
@@ -209,18 +219,18 @@ esp_err_t emac_esp_iomux_init_rmii(const eth_mac_rmii_gpio_config_t *rmii_gpio)
{
ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.clki != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII IOMUX");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, tx_en_num), emac_rmii_iomux_pins.tx_en, false),
TAG, "invalid TX_EN GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, txd0_num), emac_rmii_iomux_pins.txd0, false),
TAG, "invalid TXD0 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, txd1_num), emac_rmii_iomux_pins.txd1, false),
TAG, "invalid TXD1 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, crs_dv_num), emac_rmii_iomux_pins.crs_dv, true),
TAG,"invalid CRS_DV GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, rxd0_num), emac_rmii_iomux_pins.rxd0, true),
TAG,"invalid RXD0 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, rxd1_num), emac_rmii_iomux_pins.rxd1, true),
TAG,"invalid RXD1 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, tx_en_num), emac_rmii_iomux_pins.tx_en,
emac_io_idx.mii_tx_en_o_idx, false), TAG, "invalid TX_EN GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, txd0_num), emac_rmii_iomux_pins.txd0,
emac_io_idx.mii_txd0_o_idx, false), TAG, "invalid TXD0 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, txd1_num), emac_rmii_iomux_pins.txd1,
emac_io_idx.mii_txd1_o_idx, false), TAG, "invalid TXD1 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, crs_dv_num), emac_rmii_iomux_pins.crs_dv,
emac_io_idx.mii_crs_i_idx, true), TAG,"invalid CRS_DV GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, rxd0_num), emac_rmii_iomux_pins.rxd0,
emac_io_idx.mii_rxd0_i_idx, true), TAG,"invalid RXD0 GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, rxd1_num), emac_rmii_iomux_pins.rxd1,
emac_io_idx.mii_rxd1_i_idx, true), TAG,"invalid RXD1 GPIO number");
return ESP_OK;
}
@@ -229,7 +239,8 @@ esp_err_t emac_esp_iomux_rmii_init_tx_er(int num)
{
ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.tx_er != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII TX_ER IOMUX");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.tx_er, false), TAG, "invalid TX_ER GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.tx_er, emac_io_idx.mii_tx_er_o_idx, false),
TAG, "invalid TX_ER GPIO number");
return ESP_OK;
}
@@ -237,7 +248,8 @@ esp_err_t emac_esp_iomux_rmii_init_rx_er(int num)
{
ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.rx_er != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII RX_ER IOMUX");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.rx_er, true), TAG, "invalid RX_ER GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.rx_er, emac_io_idx.mii_rx_er_i_idx, true),
TAG, "invalid RX_ER GPIO number");
return ESP_OK;
}
@@ -245,7 +257,8 @@ esp_err_t emac_esp_iomux_mii_init_tx_er(int num)
{
ESP_RETURN_ON_FALSE(emac_mii_iomux_pins.tx_er != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support MII TX_ER IOMUX");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_mii_iomux_pins.tx_er, false), TAG, "invalid TX_ER GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_mii_iomux_pins.tx_er, emac_io_idx.mii_tx_er_o_idx, false),
TAG, "invalid TX_ER GPIO number");
return ESP_OK;
}
@@ -253,7 +266,8 @@ esp_err_t emac_esp_iomux_mii_init_rx_er(int num)
{
ESP_RETURN_ON_FALSE(emac_mii_iomux_pins.rx_er != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII RX_ER IOMUX");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_mii_iomux_pins.rx_er, true), TAG, "invalid RX_ER GPIO number");
ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_mii_iomux_pins.rx_er, emac_io_idx.mii_rx_er_i_idx, true),
TAG, "invalid RX_ER GPIO number");
return ESP_OK;
}

View File

@@ -9,10 +9,11 @@
#include "esp_log.h"
#include "esp_check.h"
#include "esp_eth.h"
#include "esp_private/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_rom_gpio.h"
#include "soc/io_mux_reg.h"
#include "esp_rom_sys.h"
#include "esp_eth_phy_802_3.h"
@@ -440,9 +441,9 @@ esp_err_t esp_eth_phy_802_3_del(phy_802_3_t *phy_802_3)
esp_err_t esp_eth_phy_802_3_reset_hw(phy_802_3_t *phy_802_3, uint32_t reset_assert_us)
{
if (phy_802_3->reset_gpio_num >= 0) {
esp_rom_gpio_pad_select_gpio(phy_802_3->reset_gpio_num);
gpio_set_direction(phy_802_3->reset_gpio_num, GPIO_MODE_OUTPUT);
gpio_func_sel(phy_802_3->reset_gpio_num, PIN_FUNC_GPIO);
gpio_set_level(phy_802_3->reset_gpio_num, 0);
gpio_output_enable(phy_802_3->reset_gpio_num);
if (reset_assert_us < 10000) {
esp_rom_delay_us(reset_assert_us);
} else {

View File

@@ -10,6 +10,8 @@
#include <inttypes.h>
#include "esp_eth_mac_spi.h"
#include "driver/gpio.h"
#include "esp_private/gpio.h"
#include "soc/io_mux_reg.h"
#include "driver/spi_master.h"
#include "esp_attr.h"
#include "esp_log.h"
@@ -23,7 +25,6 @@
#include "freertos/semphr.h"
#include "dm9051.h"
#include "sdkconfig.h"
#include "esp_rom_gpio.h"
#include "esp_rom_sys.h"
#include "esp_cpu.h"
#include "esp_timer.h"
@@ -784,9 +785,9 @@ static esp_err_t emac_dm9051_init(esp_eth_mac_t *mac)
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
esp_eth_mediator_t *eth = emac->eth;
if (emac->int_gpio_num >= 0) {
esp_rom_gpio_pad_select_gpio(emac->int_gpio_num);
gpio_set_direction(emac->int_gpio_num, GPIO_MODE_INPUT);
gpio_set_pull_mode(emac->int_gpio_num, GPIO_PULLDOWN_ONLY);
gpio_func_sel(emac->int_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(emac->int_gpio_num);
gpio_pulldown_en(emac->int_gpio_num);
gpio_set_intr_type(emac->int_gpio_num, GPIO_INTR_POSEDGE);
gpio_intr_enable(emac->int_gpio_num);
gpio_isr_handler_add(emac->int_gpio_num, dm9051_isr_handler, emac);
@@ -806,7 +807,6 @@ static esp_err_t emac_dm9051_init(esp_eth_mac_t *mac)
err:
if (emac->int_gpio_num >= 0) {
gpio_isr_handler_remove(emac->int_gpio_num);
gpio_reset_pin(emac->int_gpio_num);
}
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
return ret;
@@ -819,7 +819,6 @@ static esp_err_t emac_dm9051_deinit(esp_eth_mac_t *mac)
mac->stop(mac);
if (emac->int_gpio_num >= 0) {
gpio_isr_handler_remove(emac->int_gpio_num);
gpio_reset_pin(emac->int_gpio_num);
}
if (emac->poll_timer && esp_timer_is_active(emac->poll_timer)) {
esp_timer_stop(emac->poll_timer);

View File

@@ -13,7 +13,8 @@
#include "esp_check.h"
#include "esp_cpu.h"
#include "driver/gpio.h"
#include "esp_rom_gpio.h"
#include "esp_private/gpio.h"
#include "soc/io_mux_reg.h"
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -328,9 +329,9 @@ static esp_err_t emac_ksz8851_init(esp_eth_mac_t *mac)
emac_ksz8851snl_t *emac = __containerof(mac, emac_ksz8851snl_t, parent);
esp_eth_mediator_t *eth = emac->eth;
if (emac->int_gpio_num >= 0) {
esp_rom_gpio_pad_select_gpio(emac->int_gpio_num);
gpio_set_direction(emac->int_gpio_num, GPIO_MODE_INPUT);
gpio_set_pull_mode(emac->int_gpio_num, GPIO_PULLUP_ONLY);
gpio_func_sel(emac->int_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(emac->int_gpio_num);
gpio_pullup_en(emac->int_gpio_num);
gpio_set_intr_type(emac->int_gpio_num, GPIO_INTR_NEGEDGE); // NOTE(v.chistyakov): active low
gpio_intr_enable(emac->int_gpio_num);
gpio_isr_handler_add(emac->int_gpio_num, ksz8851_isr_handler, emac);
@@ -352,7 +353,6 @@ err:
ESP_LOGD(TAG, "MAC initialization failed");
if (emac->int_gpio_num >= 0) {
gpio_isr_handler_remove(emac->int_gpio_num);
gpio_reset_pin(emac->int_gpio_num);
}
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
return ret;
@@ -365,7 +365,6 @@ static esp_err_t emac_ksz8851_deinit(esp_eth_mac_t *mac)
mac->stop(mac);
if (emac->int_gpio_num >= 0) {
gpio_isr_handler_remove(emac->int_gpio_num);
gpio_reset_pin(emac->int_gpio_num);
}
if (emac->poll_timer && esp_timer_is_active(emac->poll_timer)) {
esp_timer_stop(emac->poll_timer);

View File

@@ -11,7 +11,8 @@
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "esp_rom_gpio.h"
#include "esp_private/gpio.h"
#include "soc/io_mux_reg.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ksz8851.h"
@@ -100,9 +101,9 @@ static esp_err_t phy_ksz8851_reset_hw(esp_eth_phy_t *phy)
// NOTE(v.chistyakov): set reset_gpio_num to a negative value can skip hardware reset phy chip
if (ksz8851->reset_gpio_num >= 0) {
ESP_LOGD(TAG, "hard reset");
esp_rom_gpio_pad_select_gpio(ksz8851->reset_gpio_num);
gpio_set_direction(ksz8851->reset_gpio_num, GPIO_MODE_OUTPUT);
gpio_func_sel(ksz8851->reset_gpio_num, PIN_FUNC_GPIO);
gpio_set_level(ksz8851->reset_gpio_num, 0);
gpio_output_enable(ksz8851->reset_gpio_num);
esp_rom_delay_us(ksz8851->reset_timeout_ms * 1000);
gpio_set_level(ksz8851->reset_gpio_num, 1);
}

View File

@@ -9,6 +9,8 @@
#include <inttypes.h>
#include "esp_eth_mac_spi.h"
#include "driver/gpio.h"
#include "esp_private/gpio.h"
#include "soc/io_mux_reg.h"
#include "driver/spi_master.h"
#include "esp_attr.h"
#include "esp_log.h"
@@ -16,7 +18,6 @@
#include "esp_system.h"
#include "esp_intr_alloc.h"
#include "esp_heap_caps.h"
#include "esp_rom_gpio.h"
#include "esp_cpu.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
@@ -812,9 +813,9 @@ static esp_err_t emac_w5500_init(esp_eth_mac_t *mac)
emac_w5500_t *emac = __containerof(mac, emac_w5500_t, parent);
esp_eth_mediator_t *eth = emac->eth;
if (emac->int_gpio_num >= 0) {
esp_rom_gpio_pad_select_gpio(emac->int_gpio_num);
gpio_set_direction(emac->int_gpio_num, GPIO_MODE_INPUT);
gpio_set_pull_mode(emac->int_gpio_num, GPIO_PULLUP_ONLY);
gpio_func_sel(emac->int_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(emac->int_gpio_num);
gpio_pullup_en(emac->int_gpio_num);
gpio_set_intr_type(emac->int_gpio_num, GPIO_INTR_NEGEDGE); // active low
gpio_intr_enable(emac->int_gpio_num);
gpio_isr_handler_add(emac->int_gpio_num, w5500_isr_handler, emac);

View File

@@ -12,7 +12,8 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_rom_gpio.h"
#include "esp_private/gpio.h"
#include "soc/io_mux_reg.h"
#include "esp_rom_sys.h"
#include "w5500.h"
@@ -153,9 +154,9 @@ static esp_err_t w5500_reset_hw(esp_eth_phy_t *phy)
phy_w5500_t *w5500 = __containerof(phy, phy_w5500_t, parent);
// set reset_gpio_num to a negative value can skip hardware reset phy chip
if (w5500->reset_gpio_num >= 0) {
esp_rom_gpio_pad_select_gpio(w5500->reset_gpio_num);
gpio_set_direction(w5500->reset_gpio_num, GPIO_MODE_OUTPUT);
gpio_func_sel(w5500->reset_gpio_num, PIN_FUNC_GPIO);
gpio_set_level(w5500->reset_gpio_num, 0);
gpio_output_enable(w5500->reset_gpio_num);
esp_rom_delay_us(100); // insert min input assert time
gpio_set_level(w5500->reset_gpio_num, 1);
}

View File

@@ -2,7 +2,7 @@
components/esp_eth/test_apps:
enable:
- if: IDF_TARGET == "esp32"
reason: only test on esp32
- if: IDF_TARGET in ["esp32", "esp32p4"]
reason: ESP32 and ESP32P4 have internal EMAC. SPI Ethernet runners are based on ESP32.
depends_components:
- esp_eth

View File

@@ -1,6 +1,6 @@
# EMAC Test
| Supported Targets | ESP32 |
| ----------------- | ----- |
| Supported Targets | ESP32 | ESP32-P4 |
| ----------------- | ----- | -------- |
This test app is used to test Ethernet MAC behavior with different chips.

View File

@@ -265,6 +265,29 @@ def test_esp_eth_ip101(dut: IdfDut) -> None:
ethernet_l2_test(dut)
# ----------- IP101 ESP32P4 -----------
@pytest.mark.esp32p4
@pytest.mark.eth_ip101
@pytest.mark.parametrize('config', [
'default_ip101_esp32p4',
], indirect=True)
def test_esp32p4_ethernet(dut: IdfDut) -> None:
ethernet_test(dut)
dut.serial.hard_reset()
ethernet_l2_test(dut)
@pytest.mark.esp32p4
@pytest.mark.eth_ip101
@pytest.mark.parametrize('config', [
'default_ip101_esp32p4',
], indirect=True)
def test_esp32p4_emac(dut: IdfDut) -> None:
ethernet_int_emac_test(dut)
dut.serial.hard_reset()
ethernet_heap_alloc_test(dut)
# ----------- LAN8720 -----------
@pytest.mark.esp32
@pytest.mark.eth_lan8720

View File

@@ -8,6 +8,4 @@ CONFIG_ESP_TASK_WDT_EN=n
CONFIG_TARGET_USE_INTERNAL_ETHERNET=y
CONFIG_TARGET_ETH_PHY_DEVICE_IP101=y
CONFIG_TARGET_USE_DEFAULT_EMAC_CONFIG=n
CONFIG_TARGET_IO_MDC=31
CONFIG_TARGET_IO_MDIO=27
CONFIG_TARGET_USE_DEFAULT_EMAC_CONFIG=y

View File

@@ -25,7 +25,9 @@ const emac_io_info_t emac_io_idx = {
.mii_col_i_idx = SIG_GPIO_OUT_IDX,
.mii_crs_i_idx = SIG_GPIO_OUT_IDX,
.mii_tx_er_o_idx = SIG_GPIO_OUT_IDX,
.mii_rx_er_i_idx = SIG_GPIO_OUT_IDX
.mii_rx_er_i_idx = SIG_GPIO_OUT_IDX,
.rmii_refclk_i_idx = SIG_GPIO_OUT_IDX,
.rmii_refclk_o_idx = SIG_GPIO_OUT_IDX
};
static const emac_iomux_info_t emac_rmii_iomux_clki[] = {

View File

@@ -25,7 +25,9 @@ const emac_io_info_t emac_io_idx = {
.mii_col_i_idx = EMAC_PHY_COL_PAD_IN_IDX,
.mii_crs_i_idx = EMAC_PHY_CRS_PAD_IN_IDX,
.mii_tx_er_o_idx = EMAC_PHY_TXER_PAD_OUT_IDX,
.mii_rx_er_i_idx = EMAC_PHY_RXER_PAD_IN_IDX
.mii_rx_er_i_idx = EMAC_PHY_RXER_PAD_IN_IDX,
.rmii_refclk_i_idx = SIG_GPIO_OUT_IDX,
.rmii_refclk_o_idx = SIG_GPIO_OUT_IDX
};
static const emac_iomux_info_t emac_rmii_iomux_clki[] = {

View File

@@ -38,6 +38,8 @@ typedef struct {
uint32_t mii_crs_i_idx;
uint32_t mii_rx_er_i_idx;
uint32_t mii_tx_er_o_idx;
uint32_t rmii_refclk_i_idx;
uint32_t rmii_refclk_o_idx;
} emac_io_info_t;
typedef struct {