Подключение ethernet LAN8720 и ESP32 Devkit C , ESP32 Devkit V1

slider
Offline
Зарегистрирован: 17.06.2014

Модуль значительно дешевле чем W5500 , но могут быть проблемы по подключению. 
Потратил много времени на разбирательство почему схема из инета не заработала, поэтому сохраню опыт здесь.   В инете попадались безответные вопросы почему эта схема тоже у некоторых не работала, пришлось разбираться самому.

В инете в основном схемы подключения к модулю именно ESP32 Devkit C , а он является расширенной версией ESP32 Devkit V1 . В нем дополнительно выведены 7 пинов , которые для обычного юзера не желательны, а то закоматозят ESP32.
- один это GPIO0 , если на нем окажется лог.0 (или даже лог1 от внешней 1.8в логики , или сама эта логика будет висеть на нем) , то при старте ESP32 , он расценит как вход в программирование, и стартовать программу он не будет.  На модуле GPIO0 соединен к кнопке FLASH ( BOOT ) , и притянут резистором 4.7к...10к   к +3.3в .  Иногда на модуле кнопка идет через резистор 470ом , что  может быть слишком много чтобы модуль реагировал на нее будучи подключенный еще к чему либо. Как и кнопка Reset.
- 6 выводов по которым ESP32 загружается из своей микросхемы памяти. И тут косяк был что китайцы подписали один пин - "GND" вместо CMD .   + обычный косяк маленький 0.1мкф кондер или его отсутствие параллельно кнопке Reset  , а должен быть 1мкф , из-за этого приходилось  для загрузки скетча жманькать кнопку FLASH ( BOOT ) . 
     Использование Devkit C выбрано из-за возможности тактирования (синхронизации) 50МГЦ от LAN8720  в сторону ESP32 , благодаря аппаратным возможностям GPIO0 . Но это можно обойти настройками в скетче , м.б. не в угоду стабильности ethernet в связке с модулем Devkit V1.

Собирал "на коленке" по распространенному рисунку проводков в инете (сверяя потом со схемой)


Один резистор  4.7к между GND и NC (никуда не подключенный пин , резерв) , с проводком на пин Enable активного кварца.  Он выключает кварц на время старта программы , потом программа по GPIO17 подает через этот NC пин , лог1 , и она запускает кварц  выводя его его из Z-состояния .  Иначе при подаче питания, выход кварца по пину nINT/RETCLK долбанет в  GPIO0 , и ESP32 откажется стартовать.
 Второй резистор и так есть на модуле ESP32 (он притягивает GPIO0  BOOT к +3.3в), его не ставил.

Скетч стандартный    \WiFi\examples\ETH_LAN8720_internal_clock   из набора  ESP32 Arduino , появляется после выбора платы ESP32 
//  в моем случае самая первая в списке - ESP32 Dev Module  , т.к. она позволят потом во вкладке "инструменты"  выбрать перепаянный флэш с 32Мбит (4МБайт) на 128Мбит (16МБайт)  . микрухи в чипдипе GD25Q127csigr ,  GD25Q127cyigr , W25Q128jveiq , ...   
Скетч получает динамический IP от вашего роутера по LAN , связывается с гуглом , получает от него дату время. Весь процесс выводит в монитор порта.

В скетче надо выставить правильно пины:

#include <ETH.h>

/*  куда выдавать синус 50МГц для модуля интернет
   * ETH_CLOCK_GPIO0_IN   - default: external clock from crystal oscillator                                              
   * ETH_CLOCK_GPIO0_OUT  - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720  
   * ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720 
   * ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720               
*/

#define ETH_CLK_MODE    ETH_CLOCK_GPIO0_IN

// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_POWER_PIN  17  // -1 

// Type of the Ethernet PHY (LAN8720 or TLK110)
#define ETH_TYPE        ETH_PHY_LAN8720

// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_ADDR 1 //  0- не работает  E (1034) emac: Timed out waiting for PHY register 0x2 to have value 0x0007(mask 0xffff). Current value 0xffff

// Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_MDC_PIN     23 // 15

// Pin# of the I²C IO signal for the Ethernet PHY
#define ETH_MDIO_PIN    18 // 2

И существует еще второй тип рабочего подключения , когда тактирование происходит от ESP32 к LAN8720 . на счет его действия на загрузку и стабильность процессора не знаю. 
здесь несколько вариаций:

1. тактирование от GPIO0 .
в скетче надо на GPIO0 наоборот выдать 50МГц , а не принимать . и управление кварцем не понадобится , 

#define ETH_CLK_MODE    ETH_CLOCK_GPIO0_OUT

// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_POWER_PIN  -1 // 17 -1 

провод от GPIO17 надо отключить,  высвобождается этот пин. 
Получается можно обойтись без резисторов , закоротив на LAN8720 пин Enable у кварца на рядом GND . пин NC не используется. 

2. тактирование от GPIO17 . 
этот вариант подойдет если у вас только ESP32 Devkit V1 , а кидать проводок на модуль на GPIO0 для реализации первого варианта как-то некрасиво. 
в скетче указываем тактирование от GPIO17

#define ETH_CLK_MODE    ETH_CLOCK_GPIO17_OUT

// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_POWER_PIN  -1 // 17 -1 

аппаратно, также как и выше, кварц должен быть выключен , пин nINT/RETCLK должен быть подключен к GPIO17 , а не к GPIO0 .  пин NC не используется. Судя по коменту в скетче , этот вариант тестирован норм.
 

// еще заметил , редко модуль LAN8720 может зависнуть , так что при удаленном объекте , то хорошо бы передергивать ему питание свободным пином ESP32 . Ток потребления  LAN8720 в работе до 90ма , что гораздо меньше W5500.  Стаб ESP32 на модуле, его запросто вывозит. Возможно ток еще немного зависит от длины провода до роутера/коммутатора . 

workpage
Offline
Зарегистрирован: 17.05.2020

Завёл dev v1 + 8720 с тактированием от 17 пина. Подтверждаю. Работает. Это наверное самый лучший вариант подключения. Нет плясок с бубном вокруг gpio0. Огромным плюсом данного подключения является тот факт, что весь софт написанный под wifi работает на ethernet практические без переделок. По этой причине пришлось "зарубить" готовую плату на w5500 и переделывать всё на 8720.

Igor Igor
Offline
Зарегистрирован: 27.06.2020

У меня плата LOLIN32 Lite. В ней отсутсвует GPIO21!

Можно ли переопределить сигнал EMAC_TX_EN на другой GPIO?

Я где-то читал что в ESP32 можно переопределить любые GPIO.

workpage
Offline
Зарегистрирован: 17.05.2020

slider, Подскажи. Как ты детектишь, что 8720 завис?

Я столкнулся с тем, что иногда при старте индикатор активности постоянно моргает и связи нет. Отключение/подключение кабеля видит. Reset решает.

Update

Нашёл причину плохого старта. Резистор R1 на 12.1к должен ТОЧНО соответствовать номиналу. В противном случае будут глюки. Вопрос с детектом перезагрузки остался.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

подскажите, где можно переназначить пины и будут ли они работать на других портах

все нужные пины уже заняты под rs485(uart2), spi, i2c, uart0.

 

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

slider пишет:

Подскажите пожалуйста, сейчас плату разрабатываю, есть свободные пины только 12,13,14, 25,26,27, 32,33, 34,35, VN, VP.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

что-то тема заглохла!

Сходу не завелось, в мониторе порта -
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1420
ho 0 tail 12 room 4
load:0x40078000,len:13540
load:0x40080400,len:3604
entry 0x400805f0
ets Jun  8 2016 00:22:57
 
rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download

скетч:
 

/*
 * проверяется под ядром 2.01
 * 
 * This sketch shows how to configure different external 
 * or internal clock sources for the Ethernet PHY
 * 
 * https://github.com/UA6EM/esp32-ethernet
 *   
*/

#include <ETH.h>

/* 
   * ETH_CLOCK_GPIO0_IN   - default: external clock from crystal oscillator
   * ETH_CLOCK_GPIO0_OUT  - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720
   * ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720
   * ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720
*/
#ifdef ETH_CLK_MODE
#undef ETH_CLK_MODE
#endif
#define ETH_CLK_MODE    ETH_CLOCK_GPIO17_OUT

// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_POWER_PIN   -1

// Type of the Ethernet PHY (LAN8720 or TLK110)
#define ETH_TYPE        ETH_PHY_LAN8720

// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_ADDR        1

// Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_MDC_PIN     23

// Pin# of the I²C IO signal for the Ethernet PHY
#define ETH_MDIO_PIN    18


static bool eth_connected = false;

void WiFiEvent(WiFiEvent_t event) {
  switch (event) {
    case SYSTEM_EVENT_ETH_START:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("esp32-ethernet");
      break;
    case SYSTEM_EVENT_ETH_CONNECTED:
      Serial.println("ETH Connected");
      break;
    case SYSTEM_EVENT_ETH_GOT_IP:
      Serial.print("ETH MAC: ");
      Serial.print(ETH.macAddress());
      Serial.print(", IPv4: ");
      Serial.print(ETH.localIP());
      if (ETH.fullDuplex()) {
        Serial.print(", FULL_DUPLEX");
      }
      Serial.print(", ");
      Serial.print(ETH.linkSpeed());
      Serial.println("Mbps");
      eth_connected = true;
      break;
    case SYSTEM_EVENT_ETH_DISCONNECTED:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case SYSTEM_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default:
      break;
  }
}

void testClient(const char * host, uint16_t port) {
  Serial.print("\nconnecting to ");
  Serial.println(host);

  WiFiClient client;
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    return;
  }
  client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
  while (client.connected() && !client.available());
  while (client.available()) {
    Serial.write(client.read());
  }

  Serial.println("closing connection\n");
  client.stop();
}

void setup() {
  Serial.begin(115200);
  WiFi.onEvent(WiFiEvent);
  ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
}


void loop() {
  if (eth_connected) {
    testClient("google.com", 80);
  }
  delay(10000);
  
}

 

rkit
Offline
Зарегистрирован: 23.11.2016

IO0 отпусти.

На китайском модуле нужно кварц отключить дополнительным пином. Ищи, вся информация есть.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

IO0 отпусти.

На китайском модуле нужно кварц отключить дополнительным пином. Ищи, вся информация есть.

пин не подключен:

Однако жеж... и далее ничего...на лане желтый горит зелёный моргает...

setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
[  1650][V][WiFiGeneric.cpp:352] _arduino_event_cb(): Ethernet Started
[  1651][D][WiFiGeneric.cpp:831] _eventCallback(): Arduino Event: 18 - ETH_START
[  1653][V][WiFiGeneric.cpp:344] _arduino_event_cb(): Ethernet Link Up
[  1659][D][WiFiGeneric.cpp:831] _eventCallback(): Arduino Event: 20 - ETH_CONNECTED
[  1664][V][WiFiGeneric.cpp:359] _arduino_event_cb(): Ethernet got newip:192.168.1.197
[  1674][D][WiFiGeneric.cpp:831] _eventCallback(): Arduino Event: 22 - ETH_GOT_IP
[  1681][D][WiFiGeneric.cpp:916] _eventCallback(): ETH IP: 192.168.1.197, MASK: 255.255.255.0, GW: 192.168.1.1

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Дело было не в бобине: )))
 

/*
   проверяется под ядром 2.01

   This sketch shows how to configure different external
   or internal clock sources for the Ethernet PHY

   https://github.com/UA6EM/esp32-ethernet

*/

#include <ETH.h>

/*
     ETH_CLOCK_GPIO0_IN   - default: external clock from crystal oscillator
     ETH_CLOCK_GPIO0_OUT  - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720
     ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720
     ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720
*/
#ifdef ETH_CLK_MODE
#undef ETH_CLK_MODE
#endif

/* 2. тактирование от GPIO17
   этот вариант подойдет если у вас только ESP32 Devkit V1 ,
   а кидать проводок на модуль на GPIO0 для реализации первого варианта как-то некрасиво.
   в скетче указываем тактирование от GPIO17
   аппаратно, также как и выше, кварц должен быть выключен , пин nINT/RETCLK должен быть
   подключен к GPIO17 , а не к GPIO0 .  пин NC не используется.
   Судя по коменту в скетче , этот вариант тестирован норм.

*/
#define ETH_CLK_MODE    ETH_CLOCK_GPIO17_OUT
// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_POWER_PIN   -1

// Type of the Ethernet PHY (LAN8720 or TLK110)
#define ETH_TYPE        ETH_PHY_LAN8720

// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_ADDR        1

// Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_MDC_PIN     23

// Pin# of the I²C IO signal for the Ethernet PHY
#define ETH_MDIO_PIN    18


static bool eth_connected = false;

void WiFiEvent(WiFiEvent_t event) {
  switch (event) {
//    case SYSTEM_EVENT_ETH_START:
      case 18:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("esp32-ethernet");
      break;
 //   case SYSTEM_EVENT_ETH_CONNECTED:
      case 20:
      Serial.println("ETH Connected");
      break;
//    case SYSTEM_EVENT_ETH_GOT_IP:
      case 22:
      Serial.print("ETH MAC: ");
      Serial.print(ETH.macAddress());
      Serial.print(", IPv4: ");
      Serial.print(ETH.localIP());
      if (ETH.fullDuplex()) {
        Serial.print(", FULL_DUPLEX");
      }
      Serial.print(", ");
      Serial.print(ETH.linkSpeed());
      Serial.println("Mbps");
      eth_connected = true;
      break;
    case SYSTEM_EVENT_ETH_DISCONNECTED:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case SYSTEM_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default:
      break;
  }
}

void testClient(const char * host, uint16_t port) {
  Serial.print("\nconnecting to ");
  Serial.println(host);

  WiFiClient client;
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    return;
  }
  client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
  while (client.connected() && !client.available());
  while (client.available()) {
    Serial.write(client.read());
  }

  Serial.println("closing connection\n");
  client.stop();
}

void setup() {
  Serial.begin(115200);
  WiFi.onEvent(WiFiEvent);
  ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
}


void loop() {
  if (eth_connected) {
    testClient("google.com", 80);
  }
  delay(10000);

}

 

workpage
Offline
Зарегистрирован: 17.05.2020

17 пин отличное решение. С нулевым много гемора со входом в режим программирования.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

встревал тут, поправил на цифровые коды, но не всё:

void WiFiEvent(WiFiEvent_t event) {
  switch (event) {
//    case SYSTEM_EVENT_ETH_START:
      case 18:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("esp32-LAN8720");
      break;
 //   case SYSTEM_EVENT_ETH_CONNECTED:
      case 20:
      Serial.println("ETH Connected");
      break;
//    case SYSTEM_EVENT_ETH_GOT_IP:
      case 22:
      Serial.print("ETH MAC: ");
      Serial.print(ETH.macAddress());
      Serial.print(", IPv4: ");
      Serial.print(ETH.localIP());
      if (ETH.fullDuplex()) {
        Serial.print(", FULL_DUPLEX");
      }
      Serial.print(", ");
      Serial.print(ETH.linkSpeed());
      Serial.println("Mbps");
      eth_connected = true;
      break;
 //   case SYSTEM_EVENT_ETH_DISCONNECTED:
    case 21:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case SYSTEM_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default:
      break;
  }
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Интересно, WIFI с ETH не конфликтуют

workpage
Offline
Зарегистрирован: 17.05.2020

Либо один интерфейс, либо другой.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

workpage пишет:
Либо один интерфейс, либо другой.

мне как раз нужна была медяшка, бюджетно )))

rkit
Offline
Зарегистрирован: 23.11.2016

Нет, не конфликтуют.

Ant123
Offline
Зарегистрирован: 23.11.2021

Тоже мучаюсь с подключением к ESP32 Wrover платки LAN8720, такой же как в первом сообщении.

На Wrover заняты GPIO16 и 17 так что приходится пользовать GPIO0.

Подключил управление кварцевым генератором на незадействованый контакт разъема и далее на GPIO4 с подтяжкой к земле.

Клок 50 МГц подключен на GPIO0 с подтяжкой к VCC через 10кОм.

Однако в 99% случаев всё осанавливаетя на Ethernet Started. Пробовал в Arduino и в ESP IDF 4.4.

На сетевом разъеме платы PHY постоянно горит зеленый светодиод. На свиче периодически вспыхивает индикация коннекта.

В редких случаях коннект все же устанавливается(при этом загорается оранжевый светодиод, пинги проходят), но после сброса ESP32 или переподключения кабеля пропадает. Иногда соединение появляется через десятки секунд или минуты после включения.

Кабель вроде пару метров, другие устройства через него коннектятся нормально.

Такое ощущение, что проблемы с автоопределением скорости/дуплекса.

Что еще можете посоветовать?

P.S. Плата LAN8720 у меня не самой лучшей версии - не подключен контакт сброса чипа к RC цепочке около резонатора. Номиналы резисторов в цепях MDIO и nRST перепутаны(если брать за основу схему платы от waveshare).

workpage
Offline
Зарегистрирован: 17.05.2020

Минимизируй длину проводов между esp и 8720. 50мгц это не шутки.

Ant123
Offline
Зарегистрирован: 23.11.2021

У меня они не сказать чтобы длинные - максимум 6 см.

У людей и длинее бывает:

rkit
Offline
Зарегистрирован: 23.11.2016

Соплями такие вещи принципиально нельзя собирать и ждать хоть какой-то надежности.

Ant123
Offline
Зарегистрирован: 23.11.2021

А кто-нибудь может проверить свой заведомо исправный модуль как указано там: https://www.youtube.com/watch?v=J7V16B0BAHI

У меня пустой модуль(подано только питание) подключается к разным сетевым устройствам с разной стабильностью.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

у меня такие же чёрные модули (пара), подключал к роутеру, на нём и смотрю, сегодня подёргаю, отпишусь

Ant123
Offline
Зарегистрирован: 23.11.2021

Также просьба замерить сопротивление дросселя между VCC и AVDD. У меня там около 2 Ом по постоянному току.

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Ant123 пишет:

Также просьба замерить сопротивление дросселя между VCC и AVDD. У меня там около 2 Ом по постоянному току.

где схему модуля глянуть?

Ant123
Offline
Зарегистрирован: 23.11.2021

Схемы модуля как на фото в первом сообщении этой темы я не нашел. Есть схема модуля от Waveshare: https://www.waveshare.com/w/upload/0/08/LAN8720-ETH-Board-Schematic.pdf

На фото дроссель находится слева внизу, но я уже его успел поменять, что однако не дало положительных результатов.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

дроссель - 2.5 ома

Модули глючат, переходят на 10 мегабит, отваливается DNS, ведут себя крайне нестабильно после того как поработают минут 5-10.
Собрано на дюпонах, надо пересобрать на плату для исключения влияния проводов

workpage
Offline
Зарегистрирован: 17.05.2020

У меня на коротких проводах нормально работал. Но это пару лет назад было. Точные подробности не помню, но на gpio0 я так и не смог его нормально запустить. В конечном итоге делал всё на gpio17. Точно что-то в самом модуле паял. Что-то с кварцевым генератором.
Но он крови, конечно, мне попил. Сложный модуль. Но зато в программном плане всё шикарно.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

У меня осталась какая-то недосказанность по ESP8266-WiFi-UART-Bridge

Хочу попробовать переделать на ESP32 и на ETH... )))
Была такая задача решилась за 1.5 килорубля, но там процессор STM

Ant123
Offline
Зарегистрирован: 23.11.2021

Подключил короткими проводами(максимум 25-30 мм до самого модуля Wrover) - без изменений.

С какими то устройствами коннектится, с какими то - нет. Лучше всего коннектится с Orange Pi PC.

Так что дело в чем-то другом. Подозреваю, что криво работает auto-negotiation...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

покопался в библиотеках, для версии ядра 2.0.1 такой код будет более правильным:

Да, еще один режим, делаем вид, что тактируемся от GPIO17 но оставляем пин неподключенным, работает однако )))
 

/*
   проверяется под ядром 2.0.1

   This sketch shows how to configure different external
   or internal clock sources for the Ethernet PHY

   https://github.com/UA6EM/esp32-ethernet

*/

#include <ETH.h>
#include <ESPmDNS.h>

/*
     ETH_CLOCK_GPIO0_IN   - default: external clock from crystal oscillator
     ETH_CLOCK_GPIO0_OUT  - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720
     ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720
     ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720
*/
#ifdef ETH_CLK_MODE
#undef ETH_CLK_MODE
#endif

/* 2. тактирование от GPIO17
   этот вариант подойдет если у вас только ESP32 Devkit V1 ,
   а кидать проводок на модуль на GPIO0 для реализации первого варианта как-то некрасиво.
   в скетче указываем тактирование от GPIO17
   аппаратно, также как и выше, кварц должен быть выключен , пин nINT/RETCLK должен быть
   подключен к GPIO17 , а не к GPIO0 .  пин NC не используется.
   Судя по коменту в скетче , этот вариант тестирован норм.

*/
#define ETH_CLK_MODE    ETH_CLOCK_GPIO17_OUT
// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_POWER_PIN   -1

// Type of the Ethernet PHY (LAN8720 or TLK110)
#define ETH_TYPE        ETH_PHY_LAN8720

// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_ADDR        1

// Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_MDC_PIN     23

// Pin# of the I²C IO signal for the Ethernet PHY
#define ETH_MDIO_PIN    18


static bool eth_connected = false;
const char devices[] = "ESP32-LAN8720";
const char my_host[] = "google.com";
const uint16_t my_port = 80;

void WiFiEvent(WiFiEvent_t event) {
  switch (event) {
    //    case SYSTEM_EVENT_ETH_START:
    case ARDUINO_EVENT_ETH_START:
    //case 18:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname(devices);
      break;
    //   case SYSTEM_EVENT_ETH_CONNECTED:
    case ARDUINO_EVENT_ETH_CONNECTED:
    //case 20:
      Serial.println("ETH Connected");
      break;
    //    case SYSTEM_EVENT_ETH_GOT_IP:
    case ARDUINO_EVENT_ETH_GOT_IP:
    //case 22:
      Serial.print("ETH MAC: ");
      Serial.print(ETH.macAddress());
      Serial.print(", IPv4: ");
      Serial.print(ETH.localIP());
      if (ETH.fullDuplex()) {
        Serial.print(", FULL_DUPLEX");
      }
      Serial.print(", ");
      Serial.print(ETH.linkSpeed());
      Serial.println("Mbps");
      eth_connected = true;
      break;
      // case SYSTEM_EVENT_ETH_DISCONNECTED:
      case ARDUINO_EVENT_ETH_DISCONNECTED:
      //case 21:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
      // case SYSTEM_EVENT_ETH_STOP:
      case ARDUINO_EVENT_ETH_STOP:
      //case 19:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default:
      break;
  }
}

void testClient(const char * host, uint16_t port) {
  Serial.print("\nconnecting to ");
  Serial.println(host);

  WiFiClient client;
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    return;
  }
  client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
  while (client.connected() && !client.available());
  while (client.available()) {
    Serial.write(client.read());
  }

  Serial.println("closing connection\n");
  client.stop();
}

void setup() {
  Serial.begin(115200);
  WiFi.onEvent(WiFiEvent);
  ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
  if (!MDNS.begin(devices)) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
}


void loop() {
  if (eth_connected) {
    testClient(my_host, my_port);
  }
  delay(10000);

}

 

Ant123
Offline
Зарегистрирован: 23.11.2021

Да, в новых библиотеках поменялись названия событий. Пробовал разные варианты тактирования - не помогает.

И электролиты по питанию навешивал, и сигнал сброса чипа от ESP заводил. После принудительного аппаратного сброса линк устанавливается, адрес меняется на 0, но перезапуск auto-negotiation во время инициализации приводит к разрыву связи.

При первом включении была кратковременная(на 1-2 секунды) переплюсовка питания. Может чип частично подгорел?

Хотя, если линк устанавливается, то работает достаточно стабильно(до переподключения кабеля).

workpage
Offline
Зарегистрирован: 17.05.2020

Из партии в 50 штук, одно из устройств не прошло тест ethernet. Светодиоды линка работали нормально. Но с программой частью было что-то не то. Долго устанавливалось соединение. После чего устройство работало нормально, но до первого отключения кабеля. ПОСЛЕ чего соединение уже не устанавливалось, хотя светодиоды линка говорили об обратном.
Замена чипа решила проблему.
Это я к тому, что брак всё-таки присутствует.

Ant123
Offline
Зарегистрирован: 23.11.2021

workpage пишет:
Замена чипа решила проблему. Это я к тому, что брак всё-таки присутствует.

А платы были такие же как на приведенных здесь фото?

Такое ощущение, что криворукому китайскому разработчику дали задание переразвести модуль Waveshare так, чтобы детали были на одной стороне, ну он и развел, как умел...

workpage
Offline
Зарегистрирован: 17.05.2020

Не. Это моя коммерческая железка.

Ant123
Offline
Зарегистрирован: 23.11.2021

Пока едет новый чип на замену, удалось добиться быстрого и стабильного появления соединения путем отключения Auto-MDIX и Auto Negotiation в драйвере PHY. Возможно в чипе вышли из строя вышли цепи, отвечающие за эти функции. Также потребовалось подключить через диод сигнал сброса LAN8720 к сигналу управления генератором чтобы соединение восстанавливалось после перезапуска ESP32.

workpage
Offline
Зарегистрирован: 17.05.2020

Зачем через диод? Имхо резистор 75-150ом по вкусу...

Ant123
Offline
Зарегистрирован: 23.11.2021

На всякий случай, чтобы сигнал сброса поднимался чуть позднее включения генератора(я восстановил неразведенное на этой версии платы соединение с RC цепочкой сброса)

workpage
Offline
Зарегистрирован: 17.05.2020

О. Те же грабли.
Убирай кондёр из цепи сброса.

Ant123
Offline
Зарегистрирован: 23.11.2021

С целью?

workpage
Offline
Зарегистрирован: 17.05.2020

RC цепь генерирует сигнал сброса (для этого и создавалась). Но поскольку сброс внешний, могут быть нюансы.

workpage
Offline
Зарегистрирован: 17.05.2020

Мне из первой партии пришлось вручную кондеры выпаивать. Были проблемы с запуском. Где-то каждый 20й раз не стартовал.

Ant123
Offline
Зарегистрирован: 23.11.2021

Какие нюансы? Без конденсатора клок и сброс появятся одновременно.

У меня, чтобы нормально сбрасывался только от RC, пришлось бы увеличить конденсатор до 10 - 20 мкф.

Ant123
Offline
Зарегистрирован: 23.11.2021

Кстати, в документе "Schematic Checklist for the LAN8720" от производителя вообще написано: "SMSC does not recommend the use of an RC circuit for this required pin reset. A reset generator / voltage monitor is one option to provide a proper reset."

workpage
Offline
Зарегистрирован: 17.05.2020

Я делюсь своим опытом. Вы можете делать как хотите.

Ant123
Offline
Зарегистрирован: 23.11.2021

Спасибо и на этом, как говорится...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Ant123 пишет:

Да, в новых библиотеках поменялись названия событий. Пробовал разные варианты тактирования - не помогает.

так выходит, что я теперь вообще не использую синхронизацию, тактируюсь от внутреннего генератора 50 мегагерц и, на удивление, всё работает сильно стабильней, обрыв связи с LAN отрабатывает стабильно, имитировал многократным разрывом-соединением кабеля, то-есть модули работают асинхронно...
ЧАстота процессора ESP32 выставлена 240 мегагерц

Ant123
Offline
Зарегистрирован: 23.11.2021

А данные при этом точно передаются? Ведь информация о соединении передается через SMI, который возможно не так зависит от 50 МГц. Впрочем, мне такой режим всё равно не подойдет, т.к. у меня APLL уже занята по своему основному предназначению.

Euronimus
Offline
Зарегистрирован: 18.12.2016

Добрый день.

Хочу предусмотреть вариант, что lan8720 отвалился и требуется его переинициализировать.
Я пробовал снять с него 3.3VDC и снова продать, при этом у меня он перестает работать.
Насколько я понял библиотека ETH не является классом, а лишь внешние функции. Тоесть я не могу создать переменную с типом ETH и очищать ее при необходимости, следовательно выполнив функцию ETH.begine() единожды нельзя снова вызвать эту функцию. Есть ли какой-то способ обойтись без перезагрузки esp32 снова запустить lan8720?

Если мои умозаключения ошибочны, поправьте, пожалуйста.

workpage
Offline
Зарегистрирован: 17.05.2020

Euronimus пишет:
Добрый день. Хочу предусмотреть вариант, что lan8720 отвалился и требуется его переинициализировать. Я пробовал снять с него 3.3VDC и снова продать, при этом у меня он перестает работать. Насколько я понял библиотека ETH не является классом, а лишь внешние функции. Тоесть я не могу создать переменную с типом ETH и очищать ее при необходимости, следовательно выполнив функцию ETH.begine() единожды нельзя снова вызвать эту функцию. Есть ли какой-то способ обойтись без перезагрузки esp32 снова запустить lan8720? Если мои умозаключения ошибочны, поправьте, пожалуйста.

ETH.stop()

жмём reset на lan8720

ETH.begin()

Но до сих пор я не могу нормально отдетектить зависание 8720. Иногда connect/disconnect видит, а данные не идут. Пинговать не вариант. Надо какие-то внутренние процессы отслеживать. Будут мысли - пишите.