From a2d669c008485f504247cadf66824826b5daaf49 Mon Sep 17 00:00:00 2001 From: Ondrej Kosta Date: Tue, 16 May 2023 16:45:41 +0200 Subject: [PATCH] Updated Ethernet README Common Troubleshooting to describe workaround when SPI issues are observed with internal EMAC connected --- examples/ethernet/README.md | 5 ++ .../components/ethernet_init/ethernet_init.c | 11 +++- examples/network/bridge/README.md | 2 +- examples/network/bridge/docs/network.drawio | 61 ------------------ examples/network/bridge/docs/network.png | Bin 17507 -> 0 bytes 5 files changed, 15 insertions(+), 64 deletions(-) delete mode 100644 examples/network/bridge/docs/network.drawio delete mode 100644 examples/network/bridge/docs/network.png diff --git a/examples/ethernet/README.md b/examples/ethernet/README.md index 46aa134729..ffc8cdfd21 100644 --- a/examples/ethernet/README.md +++ b/examples/ethernet/README.md @@ -80,3 +80,8 @@ Please consult Espressif Technical reference manual along with datasheet for spe * The data panel between ESP32's MAC and PHY needs a fixed 50MHz clock to do synchronization, which also called RMII clock. It can either be provided by an external oscillator or generated from internal APLL. The signal integrity of RMII clock is strict, so keep the trace as short as possible! * If the RMII clock is generated from internal APLL, then APLL can't be used for other purpose (e.g. I2S). +* If you observe undefined behavior (e.g. LCD glitches) of any **SPI device** which works normally when Ethernet is not connected over internal EMAC, you need to adjust EMAC DMA burst length (the DMA is shared resource between EMAC and the SPI). The same applies when you observe Ethernet frames corruption at the output of SPI Ethernet module and you use combination of internal EMAC and SPI Ethernet module as network interfaces. To configure the EMAC DMA burst length, modify internal Ethernet initialization as follows: + +```c +esp32_emac_config.dma_burst_len = ETH_DMA_BURST_LEN_4; // or other appropriate value +``` diff --git a/examples/ethernet/basic/components/ethernet_init/ethernet_init.c b/examples/ethernet/basic/components/ethernet_init/ethernet_init.c index ffb4e3f837..f19cc4b99f 100644 --- a/examples/ethernet/basic/components/ethernet_init/ethernet_init.c +++ b/examples/ethernet/basic/components/ethernet_init/ethernet_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -69,6 +69,11 @@ static esp_eth_handle_t eth_init_internal(esp_eth_mac_t **mac_out, esp_eth_phy_t // Update vendor specific MAC config based on board configuration esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; +#if CONFIG_EXAMPLE_USE_SPI_ETHERNET + // The DMA is shared resource between EMAC and the SPI. Therefore, adjust + // EMAC DMA burst length when SPI Ethernet is used along with EMAC. + esp32_emac_config.dma_burst_len = ETH_DMA_BURST_LEN_4; +#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET // Create new ESP32 Ethernet MAC instance esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // Create new PHY instance based on board configuration @@ -175,7 +180,9 @@ static esp_eth_handle_t eth_init_spi(spi_eth_module_config_t *spi_eth_module_con .mode = 0, .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, .queue_size = 20, - .spics_io_num = spi_eth_module_config->spi_cs_gpio + .spics_io_num = spi_eth_module_config->spi_cs_gpio, + .input_delay_ns = 20 + }; // Init vendor specific MAC config to default, and create new SPI Ethernet MAC instance // and new PHY instance based on board configuration diff --git a/examples/network/bridge/README.md b/examples/network/bridge/README.md index 23f88ea891..afedb06fbe 100644 --- a/examples/network/bridge/README.md +++ b/examples/network/bridge/README.md @@ -44,7 +44,7 @@ The work flow of the example is then as follows: ## Hardware Required -To run this example, it's recommended that you have either an official ESP32 Ethernet development board - [ESP32-Ethernet-Kit](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/get-started-ethernet-kit.html), or 3rd party ESP32 board as long as it's integrated with a supported Ethernet PHY chips, connected with supported SPI Ethernet modules (for example `DM9051`, `W5500` or `KSZ8851SNL`). Or ESP32(S/C series) board without internal Ethernet interface but connected to multiple SPI Ethernet modules. +To run this example, it's recommended that you have either an official ESP32 Ethernet development board - [ESP32-Ethernet-Kit](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/get-started-ethernet-kit.html), or 3rd party ESP32 board as long as it's integrated with a supported Ethernet PHY chips and connected with supported SPI Ethernet modules (for example `DM9051`, `W5500` or `KSZ8851SNL`). Or ESP32(S/C series) board without internal Ethernet interface but connected to multiple SPI Ethernet modules. Note that it is recommended to use multiple SPI Ethernet modules of the same type rather than combination of internal EMAC and SPI module since you don't need to take care of load balancing (internal EMAC has much higher bandwidth than SPI Ethernet modules). ### Pin Assignment diff --git a/examples/network/bridge/docs/network.drawio b/examples/network/bridge/docs/network.drawio deleted file mode 100644 index 8d846d467e..0000000000 --- a/examples/network/bridge/docs/network.drawio +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/network/bridge/docs/network.png b/examples/network/bridge/docs/network.png deleted file mode 100644 index 8d975df51b118a4272f749c7b1b5d052f7168131..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17507 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 Aod5s;