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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 KN{O;n*#826tY4h~