Last active
January 9, 2024 19:40
-
-
Save xk/0c08f8a2c49b35a5e0a38aad2dc6f0ee to your computer and use it in GitHub Desktop.
Investigating the LAN8710/8720A boot up sequence with an esp32.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ETH.h> | |
#include <esp_eth.h> | |
#include <esp_wifi.h> | |
#include <driver/gpio.h> | |
//#define __GEORGE__ | |
#define ETH_TXD0_PIN 19 | |
#define ETH_TXEN_PIN 21 | |
#define ETH_TXD1_PIN 22 | |
#define ETH_RXD0_PIN 25 | |
#define ETH_RXD1_PIN 26 | |
#define ETH_MODE2_PIN 27 | |
#define ETH_TYPE ETH_PHY_LAN8720 | |
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT | |
#ifdef __GEORGE__ | |
#define ETH_MDC_PIN 18 | |
#define ETH_MDIO_PIN 23 | |
#define ETH_POWER_PIN -1 | |
#define ETH_ADDR 1 | |
#else | |
#define ETH_MDC_PIN 23 | |
#define ETH_MDIO_PIN 18 | |
#define ETH_POWER_PIN 12 | |
#define ETH_ADDR 0 | |
#endif | |
char* sta_ssid= "SSID"; | |
char* sta_pwd= "PWD"; | |
char* ap_ssid= "WiFi_ESP32"; | |
char* ap_pwd= "wifiesp32pwd"; | |
uint32_t events_ctr= 0; | |
void onWiFiEvent (WiFiEvent_t id) { | |
/* | |
* WiFi Events | |
0 SYSTEM_EVENT_WIFI_READY < ESP32 WiFi ready | |
1 SYSTEM_EVENT_SCAN_DONE < ESP32 finish scanning AP | |
2 SYSTEM_EVENT_STA_START < ESP32 station start | |
3 SYSTEM_EVENT_STA_STOP < ESP32 station stop | |
4 SYSTEM_EVENT_STA_CONNECTED < ESP32 station connected to AP | |
5 SYSTEM_EVENT_STA_DISCONNECTED < ESP32 station disconnected from AP | |
6 SYSTEM_EVENT_STA_AUTHMODE_CHANGE < the auth mode of AP connected by ESP32 station changed | |
7 SYSTEM_EVENT_STA_GOT_IP < ESP32 station got IP from connected AP | |
8 SYSTEM_EVENT_STA_LOST_IP < ESP32 station lost IP and the IP is reset to 0 | |
9 SYSTEM_EVENT_STA_WPS_ER_SUCCESS < ESP32 station wps succeeds in enrollee mode | |
10 SYSTEM_EVENT_STA_WPS_ER_FAILED < ESP32 station wps fails in enrollee mode | |
11 SYSTEM_EVENT_STA_WPS_ER_TIMEOUT < ESP32 station wps timeout in enrollee mode | |
12 SYSTEM_EVENT_STA_WPS_ER_PIN < ESP32 station wps pin code in enrollee mode | |
13 SYSTEM_EVENT_AP_START < ESP32 soft-AP start | |
14 SYSTEM_EVENT_AP_STOP < ESP32 soft-AP stop | |
15 SYSTEM_EVENT_AP_STACONNECTED < a station connected to ESP32 soft-AP | |
16 SYSTEM_EVENT_AP_STADISCONNECTED < a station disconnected from ESP32 soft-AP | |
17 SYSTEM_EVENT_AP_STAIPASSIGNED < ESP32 soft-AP assign an IP to a connected station | |
18 SYSTEM_EVENT_AP_PROBEREQRECVED < Receive probe request packet in soft-AP interface | |
19 SYSTEM_EVENT_GOT_IP6 < ESP32 station or ap or ethernet interface v6IP addr is preferred | |
20 SYSTEM_EVENT_ETH_START < ESP32 ethernet start | |
21 SYSTEM_EVENT_ETH_STOP < ESP32 ethernet stop | |
22 SYSTEM_EVENT_ETH_CONNECTED < ESP32 ethernet phy link up | |
23 SYSTEM_EVENT_ETH_DISCONNECTED < ESP32 ethernet phy link down | |
24 SYSTEM_EVENT_ETH_GOT_IP < ESP32 ethernet got IP from connected AP | |
25 SYSTEM_EVENT_MAX | |
*/ | |
events_ctr++; | |
String r= ""; | |
r= "[Event #"+ String(events_ctr)+ "] "+ String(id)+ ": "; | |
switch (id) { | |
case SYSTEM_EVENT_WIFI_READY: | |
r+= "WiFi interface ready\r\n"; | |
break; | |
case SYSTEM_EVENT_SCAN_DONE: | |
r+= "Completed scan of access points\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_START: | |
r+= "STA client started\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_STOP: | |
r+= "STA clients stopped\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_CONNECTED: | |
r+= "STA Connected to access point\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_DISCONNECTED: | |
r+= "STA Disconnected from WiFi access point\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: | |
r+= "STA Authentication mode of access point has changed\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_GOT_IP: | |
r+= "STA Obtained IP address: "+ WiFi.localIP().toString()+ "\r\n"; | |
//set wifi hostname here | |
WiFi.setHostname("esp32-wifi"); | |
break; | |
case SYSTEM_EVENT_STA_LOST_IP: | |
r+= "STA Lost IP address and IP address is reset to 0\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS: | |
r+= "STA Protected Setup (WPS): succeeded in enrollee mode\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_WPS_ER_FAILED: | |
r+= "STA Protected Setup (WPS): failed in enrollee mode\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT: | |
r+= "STA Protected Setup (WPS): timeout in enrollee mode\r\n"; | |
break; | |
case SYSTEM_EVENT_STA_WPS_ER_PIN: | |
r+= "STA Protected Setup (WPS): pin code in enrollee mode\r\n"; | |
break; | |
case SYSTEM_EVENT_AP_START: | |
r+= "AP access point started\r\n"; | |
break; | |
case SYSTEM_EVENT_AP_STOP: | |
r+= "AP stopped\r\n"; | |
break; | |
case SYSTEM_EVENT_AP_STACONNECTED: | |
r+= "AP Client connected\r\n"; | |
break; | |
case SYSTEM_EVENT_AP_STADISCONNECTED: | |
r+= "AP Client disconnected\r\n"; | |
break; | |
case SYSTEM_EVENT_AP_STAIPASSIGNED: | |
r+= "AP Assigned IP address to client\r\n"; | |
break; | |
case SYSTEM_EVENT_AP_PROBEREQRECVED: | |
r+= "AP Received probe request\r\n"; | |
break; | |
case SYSTEM_EVENT_GOT_IP6: | |
r+= "IPv6 is preferred\r\n"; | |
break; | |
case SYSTEM_EVENT_ETH_START: | |
r+= "ETH started\r\n"; | |
break; | |
case SYSTEM_EVENT_ETH_STOP: | |
r+= "ETH stopped\r\n"; | |
break; | |
case SYSTEM_EVENT_ETH_CONNECTED: | |
r+= "ETH connected\r\n"; | |
break; | |
case SYSTEM_EVENT_ETH_DISCONNECTED: | |
r+= "ETH disconnected\r\n"; | |
break; | |
case SYSTEM_EVENT_ETH_GOT_IP: | |
r+= "ETH Obtained IP address\r\n"; | |
r+= "ETH MAC:"+ ETH.macAddress()+ " IP:"+ETH.localIP().toString(); | |
r+= " "+ String(ETH.linkSpeed())+ "Mbps"; | |
if (ETH.fullDuplex()) r+= "/FD"; | |
r+= "\r\n"; | |
//set eth hostname here | |
ETH.setHostname("esp32-ethernet"); | |
break; | |
} | |
Serial.print(r); | |
} | |
uint16_t bin2u16 (const char* s) { | |
uint16_t r= 0; | |
uint16_t peso= 1; | |
int len= strlen(s); | |
while (len>0) { | |
len-= 1; | |
char c= s[len]; | |
if (c == ' ') continue; | |
if (c == '1') r+= peso; | |
peso*= 2; | |
} | |
return r; | |
} | |
void eth_off () { | |
#ifdef __GEORGE__ | |
//I use another pin (5 not 12) with reversed polarity. | |
pinMode(5, OUTPUT); | |
digitalWrite(5, 1); | |
//esp_err_t err= gpio_set_drive_capability(gpio_num_t GPIO_NUM_12, gpio_drive_cap_t GPIO_DRIVE_CAP_3); | |
gpio_set_drive_capability(GPIO_NUM_5, GPIO_DRIVE_CAP_3); | |
#else | |
pinMode(ETH_POWER_PIN, OUTPUT); | |
digitalWrite(ETH_POWER_PIN, 0); | |
//esp_err_t err= gpio_set_drive_capability(gpio_num_t GPIO_NUM_12, gpio_drive_cap_t GPIO_DRIVE_CAP_3); | |
gpio_set_drive_capability(GPIO_NUM_12, GPIO_DRIVE_CAP_3); | |
#endif | |
//Turn off all the pins connected to the 8710. | |
pinMode(ETH_MDC_PIN, INPUT_PULLDOWN); | |
pinMode(ETH_TXD0_PIN, INPUT_PULLDOWN); | |
pinMode(ETH_TXD1_PIN, INPUT_PULLDOWN); | |
pinMode(ETH_TXEN_PIN, INPUT_PULLDOWN); | |
pinMode(17, INPUT_PULLDOWN); | |
pinMode(ETH_RXD0_PIN, INPUT_PULLDOWN); | |
pinMode(ETH_RXD1_PIN, INPUT_PULLDOWN); | |
pinMode(ETH_MODE2_PIN, INPUT_PULLDOWN); | |
pinMode(ETH_MDIO_PIN, INPUT_PULLDOWN); | |
} | |
void eth_on () { | |
//Some pins MUST be HIGH when turning on. | |
//this is MODE0, must be 1 | |
pinMode(ETH_RXD0_PIN, INPUT_PULLUP); | |
//this is MODE1, must be 1 | |
pinMode(ETH_RXD1_PIN, INPUT_PULLUP); | |
//this is MODE2, must be 1 | |
pinMode(ETH_MODE2_PIN, INPUT_PULLUP); | |
//this should be 1 | |
pinMode(ETH_MDIO_PIN, INPUT_PULLUP); | |
//because the pullups are weak... | |
delay(10); | |
#ifdef __GEORGE__ | |
//I use another pin (5 not 12) with reversed polarity. | |
pinMode(5, OUTPUT); | |
digitalWrite(5, 0); | |
//esp_err_t err= gpio_set_drive_capability(gpio_num_t GPIO_NUM_12, gpio_drive_cap_t GPIO_DRIVE_CAP_3); | |
gpio_set_drive_capability(GPIO_NUM_5, GPIO_DRIVE_CAP_3); | |
#else | |
pinMode(ETH_POWER_PIN, OUTPUT); | |
digitalWrite(ETH_POWER_PIN, 1); | |
gpio_set_drive_capability(GPIO_NUM_12, GPIO_DRIVE_CAP_3); | |
#endif | |
} | |
String say_hi () { | |
String r= ""; | |
//Fecha y hora a la que se compiló esto. | |
//Ver: Arduino predefined constants: https://gist.github.com/ah01/762576 | |
r+= String("\r\n")+ __DATE__+ " "+ __TIME__; | |
r+= String()+ "\r\nIDF-VERSION: "+ esp_get_idf_version()+ "\r\n"; | |
r+= "ESP. getSketchSize(): "+ String(ESP.getSketchSize())+ "\r\n"; | |
r+= "ESP.getFreeSketchSpace(): "+ String(ESP.getFreeSketchSpace())+ "\r\n"; | |
{ | |
//ver: | |
//https://github.com/espressif/esp-idf/blob/master/examples/system/base_mac_address/main/base_mac_address_example_main.c | |
uint8_t base_mac_addr[6] = {0}; | |
if (esp_read_mac(base_mac_addr, ESP_MAC_WIFI_STA) == ESP_OK) { | |
r+= "STA MAC Address: "; | |
for (int i=0 ; i<6 ; i++) { | |
String hex= String(base_mac_addr[i], HEX); | |
if (hex.length()<2) hex= "0"+ hex; | |
r+= hex+ " "; | |
} | |
r+= "\r\n"; | |
} | |
if (esp_read_mac(base_mac_addr, ESP_MAC_WIFI_SOFTAP) == ESP_OK) { | |
r+= " AP MAC Address: "; | |
for (int i=0 ; i<6 ; i++) { | |
String hex= String(base_mac_addr[i], HEX); | |
if (hex.length()<2) hex= "0"+ hex; | |
r+= hex+ " "; | |
} | |
r+= "\r\n"; | |
} | |
if (esp_read_mac(base_mac_addr, ESP_MAC_BT) == ESP_OK) { | |
r+= " BT MAC Address: "; | |
for (int i=0 ; i<6 ; i++) { | |
String hex= String(base_mac_addr[i], HEX); | |
if (hex.length()<2) hex= "0"+ hex; | |
r+= hex+ " "; | |
} | |
r+= "\r\n"; | |
} | |
if (esp_read_mac(base_mac_addr, ESP_MAC_ETH) == ESP_OK) { | |
r+= "ETH MAC Address: "; | |
for (int i=0 ; i<6 ; i++) { | |
String hex= String(base_mac_addr[i], HEX); | |
if (hex.length()<2) hex= "0"+ hex; | |
r+= hex+ " "; | |
} | |
r+= "\r\n"; | |
} | |
} | |
r+= "\r\nHi!\a\a\a "; | |
return r; | |
} | |
void dr () { | |
Serial.print(" r0:"); | |
Serial.print(esp_eth_smi_read(0), HEX); | |
Serial.print(" r1:"); | |
Serial.print(esp_eth_smi_read(1), HEX); | |
Serial.print(" r2:"); | |
Serial.print(esp_eth_smi_read(2), HEX); | |
Serial.print(" r3:"); | |
Serial.print(esp_eth_smi_read(3), HEX); | |
Serial.print(" r4:"); | |
Serial.print(esp_eth_smi_read(4), HEX); | |
Serial.print(" r5:"); | |
Serial.print(esp_eth_smi_read(5), HEX); | |
Serial.print(" r6:"); | |
Serial.print(esp_eth_smi_read(6), HEX); | |
Serial.print(" r16:"); | |
Serial.print(esp_eth_smi_read(16), HEX); | |
Serial.print(" r17:"); | |
Serial.print(esp_eth_smi_read(17), HEX); | |
Serial.print(" r18:"); | |
Serial.print(esp_eth_smi_read(18), HEX); | |
Serial.print(" r26:"); | |
Serial.print(esp_eth_smi_read(26), HEX); | |
Serial.print(" r27:"); | |
Serial.print(esp_eth_smi_read(27), HEX); | |
Serial.print(" r28:"); | |
Serial.print(esp_eth_smi_read(28), HEX); | |
Serial.print(" r29:"); | |
Serial.print(esp_eth_smi_read(29), HEX); | |
Serial.print(" r30:"); | |
Serial.print(esp_eth_smi_read(30), HEX); | |
Serial.print(" r31:"); | |
Serial.print(esp_eth_smi_read(31), HEX); | |
Serial.print("\r\n"); | |
} | |
void eth_10 () { | |
//Force 10BASE-T max. | |
esp_eth_smi_write(4, bin2u16("000000 0 0011 00001")); | |
//Force renegotiation. | |
esp_eth_smi_write(0, bin2u16("0001 0010 00000000")); | |
} | |
void eth_100 () { | |
//Allow 100BASE-T. | |
esp_eth_smi_write(4, bin2u16("000000 0 1111 00001")); | |
//Force renegotiation. | |
esp_eth_smi_write(0, bin2u16("0001 0010 00000000")); | |
} | |
void commander (String cmd) { | |
int ok= 1; | |
if (cmd == "dr") dr(); | |
else if (cmd == "ethon") eth_on(); | |
else if (cmd == "eth10") eth_10(); | |
else if (cmd == "eth100") eth_100(); | |
else if (cmd == "ethoff") eth_off(); | |
else if (cmd == "wifioff") WiFi.mode(WIFI_OFF); | |
else if (cmd == "wifiap") WiFi.softAP(ap_ssid, ap_pwd); | |
else if (cmd == "wifista") WiFi.begin(sta_ssid, sta_pwd); | |
else if (cmd == "reboot") { | |
eth_off(); | |
WiFi.mode(WIFI_OFF); | |
esp_restart(); | |
} | |
else ok= 0; | |
if (ok) Serial.print(" ok\r\n"); | |
else Serial.print(" Watt?\r\n"); | |
} | |
String command= ""; | |
void console_handle () { | |
int c; | |
while (Serial.available()) { | |
c= Serial.read(); | |
if ((c == '\r') || (c == '\n')) { | |
if (command.length()) commander(command); | |
else Serial.print("\r\n"); | |
command= ""; | |
} | |
else { | |
Serial.write(c); | |
command+= (char)c; | |
} | |
} | |
} | |
void setup () { | |
unsigned long now= millis(); | |
eth_off(); | |
Serial.begin(115200); | |
Serial.setDebugOutput(true); | |
Serial.print(say_hi()); | |
WiFi.onEvent(onWiFiEvent); | |
WiFi.mode(WIFI_OFF); | |
while ((millis()-now)<888) ; | |
eth_on(); | |
//delay(1); | |
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE); | |
eth_10(); | |
} | |
uint32_t ctr= 0; | |
uint8_t primeravez= 1; | |
void loop () { | |
ctr+= 1; | |
if (primeravez) { | |
primeravez= 0; | |
Serial.print("We're in the loop()\r\n\r\n"); | |
} | |
console_handle(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
When I try to build the above code in the Arduino IDE I get the following compile errors:
'esp_eth_smi_read' was not declared in this scope
'esp_eth_smi_write' was not declared in this scope
I am obviously missing something. I need to turn off auto negotiation and set the mode to 100Mb. Any help you can provide in pointing me in the right direction would be greatly appreciated.
Thanks