Skip to content

Commit a1acc55

Browse files
sauttefkCurclamas
authored andcommitted
Allow configuration of Ethernet PHY clock source (espressif#916)
* Allow configuration of Ethernet PHY clock source Refer to espressif/esp-idf#1127 The internal APLL can be used to generate the 50MHz clock for the internal EMAC and the external Ethernet PHY. The clock can either be input on GPIO0 (as before) or output on GPIO0, GPIO16 or GPIO17 (only GPIO17 extensively tested). New example available. * Allow configuration of Ethernet PHY clock source Refer to espressif/esp-idf#1127 The internal APLL can be used to generate the 50MHz clock for the internal EMAC and the external Ethernet PHY. The clock can either be input on GPIO0 (as before) or output on GPIO0, GPIO16 or GPIO17 (only GPIO17 extensively tested). New example available.
1 parent 368839d commit a1acc55

File tree

3 files changed

+109
-3
lines changed

3 files changed

+109
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
This sketch shows how to configure different external or internal clock sources for the Ethernet PHY
3+
*/
4+
5+
#include <ETH.h>
6+
7+
/*
8+
* ETH_CLOCK_GPIO0_IN - default: external clock from crystal oscillator
9+
* ETH_CLOCK_GPIO0_OUT - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720
10+
* ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720
11+
* ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720
12+
*/
13+
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
14+
15+
// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
16+
#define ETH_POWER_PIN -1
17+
18+
// Type of the Ethernet PHY (LAN8720 or TLK110)
19+
#define ETH_TYPE ETH_PHY_LAN8720
20+
21+
// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
22+
#define ETH_ADDR 0
23+
24+
// Pin# of the I²C clock signal for the Ethernet PHY
25+
#define ETH_MDC_PIN 15
26+
27+
// Pin# of the I²C IO signal for the Ethernet PHY
28+
#define ETH_MDIO_PIN 2
29+
30+
31+
static bool eth_connected = false;
32+
33+
void WiFiEvent(WiFiEvent_t event) {
34+
switch (event) {
35+
case SYSTEM_EVENT_ETH_START:
36+
Serial.println("ETH Started");
37+
//set eth hostname here
38+
ETH.setHostname("esp32-ethernet");
39+
break;
40+
case SYSTEM_EVENT_ETH_CONNECTED:
41+
Serial.println("ETH Connected");
42+
break;
43+
case SYSTEM_EVENT_ETH_GOT_IP:
44+
Serial.print("ETH MAC: ");
45+
Serial.print(ETH.macAddress());
46+
Serial.print(", IPv4: ");
47+
Serial.print(ETH.localIP());
48+
if (ETH.fullDuplex()) {
49+
Serial.print(", FULL_DUPLEX");
50+
}
51+
Serial.print(", ");
52+
Serial.print(ETH.linkSpeed());
53+
Serial.println("Mbps");
54+
eth_connected = true;
55+
break;
56+
case SYSTEM_EVENT_ETH_DISCONNECTED:
57+
Serial.println("ETH Disconnected");
58+
eth_connected = false;
59+
break;
60+
case SYSTEM_EVENT_ETH_STOP:
61+
Serial.println("ETH Stopped");
62+
eth_connected = false;
63+
break;
64+
default:
65+
break;
66+
}
67+
}
68+
69+
void testClient(const char * host, uint16_t port) {
70+
Serial.print("\nconnecting to ");
71+
Serial.println(host);
72+
73+
WiFiClient client;
74+
if (!client.connect(host, port)) {
75+
Serial.println("connection failed");
76+
return;
77+
}
78+
client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
79+
while (client.connected() && !client.available());
80+
while (client.available()) {
81+
Serial.write(client.read());
82+
}
83+
84+
Serial.println("closing connection\n");
85+
client.stop();
86+
}
87+
88+
void setup() {
89+
Serial.begin(115200);
90+
WiFi.onEvent(WiFiEvent);
91+
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
92+
}
93+
94+
95+
void loop() {
96+
if (eth_connected) {
97+
testClient("google.com", 80);
98+
}
99+
delay(10000);
100+
}

Diff for: libraries/WiFi/src/ETH.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern void tcpipInit();
3030
static int _eth_phy_mdc_pin = -1;
3131
static int _eth_phy_mdio_pin = -1;
3232
static int _eth_phy_power_pin = -1;
33+
static eth_clock_mode_t _eth_clk_mode = ETH_CLOCK_GPIO0_IN;
3334
static eth_phy_power_enable_func _eth_phy_power_enable_orig = NULL;
3435

3536
static void _eth_phy_config_gpio(void)
@@ -56,7 +57,7 @@ ETHClass::ETHClass():initialized(false),started(false),staticIP(false)
5657
ETHClass::~ETHClass()
5758
{}
5859

59-
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type)
60+
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode)
6061
{
6162
esp_err_t err;
6263
if(initialized){
@@ -84,6 +85,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ
8485
}
8586

8687
eth_config.phy_addr = (eth_phy_base_t)phy_addr;
88+
eth_config.clock_mode = clock_mode;
8789
eth_config.gpio_config = _eth_phy_config_gpio;
8890
eth_config.tcpip_input = tcpip_adapter_eth_input;
8991
if(_eth_phy_power_pin >= 0){

Diff for: libraries/WiFi/src/ETH.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@
4444
#define ETH_PHY_MDIO 18
4545
#endif
4646

47-
typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_MAX} eth_phy_type_t;
47+
#ifndef ETH_CLK_MODE
48+
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
49+
#endif
50+
51+
typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_MAX } eth_phy_type_t;
4852

4953
class ETHClass {
5054
private:
@@ -56,7 +60,7 @@ class ETHClass {
5660
ETHClass();
5761
~ETHClass();
5862

59-
bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE);
63+
bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE);
6064

6165
// NOT WORKING YET!
6266
//bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);

0 commit comments

Comments
 (0)