espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.69k stars 7.29k forks source link

[TW#24566] LAN8720 TX issue with ethernet_example (IDFGH-1393) #2164

Closed cnlohr closed 5 years ago

cnlohr commented 6 years ago

I've been trying several things and went through two revs of the board with my LAN8720 PHY to no avail. I can easily receive packets when I hook them in the inner workings of the MAC stack, but I cannot seem to transmit anything at all.

I've spent well over 20 hours on this so far and tried cross-posting the issue over on the ESP32 forums, no traction there yet. https://www.esp32.com/viewtopic.php?f=12&t=6322&p=27381#p27381

I've tried many different clock settings and all have the same issue. I've always been using the ESP32 as the clock source, so GPIO16, GPIO17 or GPIO0 out. Always can RX packets, no packets get TX'd. So, no DHCP.

It feels more like it may be an issue within the way it's sending the data within the MAC. The only real deviation I'm making from the existing example is bootstrapping the chip, but I don't think that would mess it up.

    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pin_bit_mask = (1<<2)| (1<<25)| (1<<26)|(1<<27)|(1<<13);
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);
    gpio_set_level(13, 0); //SET PHYAD0 "RXER" ... or on the KSZ, 0 indicates no factory reset.
    gpio_set_level(25, 1);  //SET MODE 0, 1, 2
    gpio_set_level(27, 1); //SET TO 1 FOR LAN8720
    gpio_set_level(26, 1);
    gpio_set_level(2, 0);

    ESP_LOGI( TAG, "Start up" );

    esp_err_t ret = ESP_OK;
    tcpip_adapter_init();
    esp_event_loop_init(NULL, NULL);

    //Exit reset.
    gpio_set_level(2, 1);

    //Reset configuration on pins...
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pin_bit_mask = (1<<25)| (1<<26)|(1<<27)|(1<<13);
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);

    eth_config_t config = DEFAULT_ETHERNET_PHY_CONFIG;
    /* Set the PHY address in the example configuration */
    config.phy_addr = CONFIG_PHY_ADDRESS;
    config.gpio_config = eth_gpio_config_rmii;
    config.tcpip_input = tcpip_adapter_eth_input;
    config.clock_mode = CONFIG_PHY_CLOCK_MODE;

Right now this is my config:

CONFIG_PHY_TLK110=
CONFIG_PHY_LAN8720=y
CONFIG_PHY_KSZ8081=
CONFIG_PHY_ADDRESS=0
CONFIG_PHY_CLOCK_GPIO0_IN=
CONFIG_PHY_CLOCK_GPIO0_OUT=y
CONFIG_PHY_CLOCK_GPIO16_OUT=
CONFIG_PHY_CLOCK_GPIO17_OUT=
CONFIG_PHY_CLOCK_MODE=1
CONFIG_PHY_USE_POWER_PIN=
CONFIG_PHY_SMI_MDC_PIN=23
CONFIG_PHY_SMI_MDIO_PIN=18

Just checking - has anyone ever verified you can use a LAN8720 in the XIN mode where the ESP32 provides the RMII clock? I.e. no extra 50/25 MHz crystal?

igrr commented 6 years ago

I think at least @sauttefk had reported success with LAN8720 and clock supplied by ESP32 here: https://github.com/espressif/esp-idf/pull/1127#issuecomment-340727923

cnlohr commented 6 years ago

Just FYI - I was able to get it working using GPIO17, inverted output. It looks like there may be phase issues with my board. Currently experimenting.

Matheus-Garbelini commented 6 years ago

@igrr We may need more testing with low latency inverters such as NL17SZ00DFT2G on GPIO16/0. The external 50Mhz crystal and the bootstrap circuit for the crystal add some additional costs that wouldn't be needed. Also would allow to use ESP32-WROVER which have GPIO16/17 used by psram.

cnlohr commented 6 years ago

Indeed 16/17 is pretty critical. I am not personally using the psram, but I could see myself using that in the near future.

suda-morris commented 6 years ago

@cnlohr Actually you shouldn't use GPIO16/17 to output 50MHz clock for Ethernet if you want to use PSRAM at the same time. GPIO0 can not be used to output 50MHz clock in any situation, this bug has been fixed in the lasted release. May I ask you a question, have been succeed with your LAN8720 board now?

sauttefk commented 6 years ago

@suda-morris But I am actually using GPIO0 as output and it is working

Matheus-Garbelini commented 6 years ago

@sauttefk Did you use any inverter IC? If so, which one?

cnlohr commented 5 years ago

Yeah... uuhh... Definitely don't get rid of GPIO0, @suda-morris ... I right now am using GPIO16/17, but will be switching it to GPIO0 with an inverter soon.

negativekelvin commented 5 years ago

@sauttefk have you scoped the clkout on gpio0 and gpio16 side by side? Is there any difference?

suda-morris commented 5 years ago

@sauttefk Sounds interesting. Yes, GPIO0 can output the clock of APLL if we set the register PIN_CTRL to value 6, but how did you know this? By the way, have you added any external chip to modify the phase of the clock output from GPIO0 so that it can work for LAN8720?

@negativekelvin GPIO0 seems like output the same clock as GPIO16 regardless of the different of their Vpp.

@cnlohr I'm looking forward to your good news.

sauttefk commented 5 years ago

@suda-morris

Yes, GPIO0 can output the clock of APLL if we set the register PIN_CTRL to value 6, but how did you know this?

Because I read the datasheet and committed the code to use GPIO16, GPIO17 and GPIO0 as EMAC clock output. See here https://github.com/espressif/esp-idf/commit/f324458b6ad26d31a5ee5309ea1ac52c5d5654f6#diff-d6d5d1b5f7eb8740026fb9f036bb28af You removed this here https://github.com/espressif/esp-idf/commit/ec07112f5b0c4b7fec4825083c9353644f421b0a#diff-add484727a0710bb807e8138b9140d23 and ignored my protest :-(

@Matheus-Garbelini I just used the GPIO0 pin, but without any other components on it except for a 22Ω series resistor between GPIO0 and the clock input of the LAN8720

sauttefk commented 5 years ago

GPIO0 can not be used to output 50MHz clock in any situation, this bug has been fixed in the lasted release.

Yes, but this also applies to other pins in other situations. I think someone who adds an Ethernet port to the ESP32 knows what he does and that there may be constraints.

suda-morris commented 5 years ago

@sauttefk I'm sorry for removing part of your code because I haven't tested GPIO0 output mode successfully and also many customers have difficulty in the mode. But just now, after I added an inverter after GPIO0, the Ethernet starts to work happily. Later I will add this mode again in Ethernet driver and will add more suggestion on how to make this mode work. Thank you for your effort in ESP-IDF.

Matheus-Garbelini commented 5 years ago

@sudda-morris which inverter IC you've used?

suda-morris commented 5 years ago

@Matheus-Garbelini For inverter, you have a lot of choice. I used SN74AUP1T14 for a try.

Matheus-Garbelini commented 5 years ago

@suda-morris I was planing in using a NAND inverter for high speed such as NL17SZ00, but as you tested with the SN74AUP1T14 I'm fine then. Also, have you added some series resistors after this IC (22ohms for instance)? Thank you.

suda-morris commented 5 years ago

@Matheus-Garbelini There is a 470Ω resistor between GPIO0 and input of inverter in my case.

cnlohr commented 5 years ago

I never thought about that, but that could really help me. I've been having synchronization issues with mine over GPIO16, I think this could really help out! I will have to try adding that resistor for my GPIO0 solution.

Matheus-Garbelini commented 5 years ago

@suda-morris Thank you. Is there a reason for this value, or you got to it by testing? It seems bigger then the values I usually see for these connections (less than 100ohms). Thank you.

suda-morris commented 5 years ago

@Matheus-Garbelini Ah, I also have no idea about it because the board I use just have this resistor connected to GPIO0. Since commonly we don't choose such a "large" series resistor in this situation, you can take 47Ω as a try, which I think will also work.

suda-morris commented 5 years ago

@Matheus-Garbelini Just asked HW team about it, 470Ω can minimize the impact of GPIO0 on RF RX performance.

Matheus-Garbelini commented 5 years ago

@suda-morris Thank you very much. I'll use this then

suda-morris commented 5 years ago

Hi all, we will support up to 5 different kinds of Ethernet PHY in the next Major relase, and support GPIO0 to output 50MHz RMII clock in the new emac driver. We have tested this feature with PSRAM at the same time. So for now, I will close this issue. If anyone have similar problem, feel free to reopen this issue or post your questions on our forum.

cnlohr commented 5 years ago

Thank you!

kitts82 commented 5 years ago

Hi all, we will support up to 5 different kinds of Ethernet PHY in the next Major relase, and support GPIO0 to output 50MHz RMII clock in the new emac driver. We have tested this feature with PSRAM at the same time.

When is this release exptected? Or when will it be possible in master to use GPIO0 as clock out?

kitts82 commented 5 years ago

In my current setup, gpio0 in works fine but gpio0 out is not working. On observing with an oscilloscope, I can see that there is a clock on gpio out but the signal amplitude is less than 200mV. However the oscillator output on the waveshare board is almost 2V. Could the clock amplitude be the issue (timeout configuring the lan8720)? And if yes, how can it be increased?

ESP-IDF v3.2, ESP32-PICO-KIT, waveshare LAN8720 https://esp32.com/viewtopic.php?f=12&t=11027&sid=0cdb323bd1483c46179f92f52f7ce068

mrdc commented 3 years ago

we will support up to 5 different kinds of Ethernet PHY in the next Major relase, and support GPIO0 to output 50MHz RMII clock in the new emac driver. We have tested this feature with PSRAM at the same time.

@suda-morris

Hi, will you be so kind to tell me what is the right approach for ESP32 Wrover for LAN8720: to use GPIO_0 as output or as input? Is it safe to use GPIO_0 as output in hardware design? Shouldn't this feature be removed in future SDK versions? Because I've read here https://github.com/espressif/esp-idf/issues/1110#issuecomment-336325248 that it's a hack: Sending ethernet clock output via GPIO0 is somewhat of a hack...

scwgoire commented 2 years ago

Hi there! I'm having the exact same problem: RX works fine, TX'd packets are not received and no error is reported.

@cnlohr can you tell how you managed to get this working reliably ? What where the items you focused on?

The TXD0, TXD1 and TX_EN signals look good (when a packet is sent from ESP, I can observe data on TXDx while TX_EN is high). PHY Clock is supplied by ESP32 GPIO17. (I don't have PSRAM so GPIO17 is fine for me) PHY registers are in good shape, didn't see any oddity there.

Could it be magnetics related ? Is there a way RX path is ok but TX not due to magnetics ? (I'm using H2019NL from Pulse)

Thanks!

kitts82 commented 2 years ago

In my case, I went with an external 50MHz clock to solve the issue.

scwgoire commented 2 years ago

In my case, I went with an external 50MHz clock to solve the issue.

Outch, that hurts. Thanks for your quick insight! Maybe someone from Espressif would like to comment on that? It would be nice to document technical challenges associated with going for a design based on ESP internal clock output.

suda-morris commented 2 years ago

Hi @mrdc Theoretically speaking, GPIO0 is OK for generating the RMII clock but, as this is derived from internal APLL. But it's not easy to get a clean and stable PCB trace for that clock. So someone succeeds and someone fails. To my preference, I suggest using GPIO input mode, as using an external crystal or oscillator is much stable!

DatanoiseTV commented 2 years ago

I am having this issue with my custom boards using GPIO0 for clock output (assembled by JLCPCB) RX works fine, but DHCP/TX fails. The traces on the PCB from ESP32 to LAN8720A are only 20-30mm.

FM77xNQWUAIW0k7

FM77xNJXwAowok-

sauttefk commented 2 years ago

When using GPIO0 as clock for the PHY, GPIO0 has to be inverted e.g. using a 74LVC1G04. Also any capacitive load on GPIO0 has to be kept low (a 74LVC1G125 could be used).

Bildschirmfoto 2022-03-06 um 22 23 30
DatanoiseTV commented 2 years ago

@sauttefk Oh, so this is why RX works and TX not? Guess I will have to use those boards as decoration and make new ones. Can you verify that my schematic above is correct for the rest? I left REFCLKO/nINT disconnected as well.

sauttefk commented 2 years ago

@DatanoiseTV Oh, so this is why RX works and TX not? Different timing... see timing diagrams of LAN8720 and ESP32

sauttefk commented 2 years ago

@DatanoiseTV

Can you verify that my schematic above is correct for the rest? I left REFCLKO/nINT disconnected as well.

Checkout https://github.com/OLIMEX/ESP32-POE/blob/master/HARDWARE/ESP32-PoE-hardware-revision-G1/ESP32-PoE_Rev_G1.pdf for a working Ethernet schematic with PHY-CLK via GPIO17

DatanoiseTV commented 2 years ago

Checkout https://github.com/OLIMEX/ESP32-POE/blob/master/HARDWARE/ESP32-PoE-hardware-revision-G1/ESP32-PoE_Rev_G1.pdf for a working Ethernet schematic with PHY-CLK via GPIO17

I did before, but I cannot use GPIO16/17 because I am using the PSRAM (WROVER module).

DatanoiseTV commented 2 years ago

I was busy with some other projects, but wanted to investigate this issue again. So if a module like WROVER is used, I need to use GPIO0 and invert the signal?