Skip to content

Commit df51bc3

Browse files
fix(eth): Set the ETH properties at the correct time (espressif#11182)
* fix(eth): Set the ETH properties at the correct time * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 9dddc14 commit df51bc3

File tree

2 files changed

+82
-4
lines changed

2 files changed

+82
-4
lines changed

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

+75-4
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ void ETHClass::_onEthEvent(int32_t event_id, void *event_data) {
124124
}
125125

126126
ETHClass::ETHClass(uint8_t eth_index)
127-
: _eth_handle(NULL), _eth_index(eth_index), _phy_type(ETH_PHY_MAX), _glue_handle(NULL), _mac(NULL), _phy(NULL)
127+
: _eth_handle(NULL), _eth_index(eth_index), _phy_type(ETH_PHY_MAX), _glue_handle(NULL), _mac(NULL), _phy(NULL), _eth_started(false), _link_speed(100),
128+
_full_duplex(true), _auto_negotiation(true)
128129
#if ETH_SPI_SUPPORTS_CUSTOM
129130
,
130131
_spi(NULL)
@@ -351,6 +352,19 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i
351352
return false;
352353
}
353354

355+
// auto negotiation needs to be disabled to change duplex mode and link speed
356+
if (!_auto_negotiation) {
357+
if (!_setAutoNegotiation(_auto_negotiation)) {
358+
return false;
359+
}
360+
if (!_setFullDuplex(_full_duplex)) {
361+
return false;
362+
}
363+
if (!_setLinkSpeed(_link_speed)) {
364+
return false;
365+
}
366+
}
367+
354368
if (_eth_ev_instance == NULL && esp_event_handler_instance_register(ETH_EVENT, ESP_EVENT_ANY_ID, &_eth_event_cb, NULL, &_eth_ev_instance)) {
355369
log_e("event_handler_instance_register for ETH_EVENT Failed!");
356370
return false;
@@ -367,6 +381,8 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i
367381
return false;
368382
}
369383

384+
_eth_started = true;
385+
370386
if (!perimanSetPinBus(_pin_rmii_clock, ESP32_BUS_TYPE_ETHERNET_CLK, (void *)(this), -1, -1)) {
371387
goto err;
372388
}
@@ -788,6 +804,19 @@ bool ETHClass::beginSPI(
788804
return false;
789805
}
790806

807+
// auto negotiation needs to be disabled to change duplex mode and link speed
808+
if (!_auto_negotiation) {
809+
if (!_setAutoNegotiation(_auto_negotiation)) {
810+
return false;
811+
}
812+
if (!_setFullDuplex(_full_duplex)) {
813+
return false;
814+
}
815+
if (!_setLinkSpeed(_link_speed)) {
816+
return false;
817+
}
818+
}
819+
791820
if (_eth_ev_instance == NULL && esp_event_handler_instance_register(ETH_EVENT, ESP_EVENT_ANY_ID, &_eth_event_cb, NULL, &_eth_ev_instance)) {
792821
log_e("event_handler_instance_register for ETH_EVENT Failed!");
793822
return false;
@@ -803,6 +832,8 @@ bool ETHClass::beginSPI(
803832
return false;
804833
}
805834

835+
_eth_started = true;
836+
806837
// If Arduino's SPI is used, cs pin is in GPIO mode
807838
#if ETH_SPI_SUPPORTS_CUSTOM
808839
if (_spi == NULL) {
@@ -897,6 +928,9 @@ void ETHClass::end(void) {
897928
while (getStatusBits() & ESP_NETIF_STARTED_BIT) {
898929
delay(10);
899930
}
931+
932+
_eth_started = false;
933+
900934
//delete glue first
901935
if (_glue_handle != NULL) {
902936
if (esp_eth_del_netif_glue(_glue_handle) != ESP_OK) {
@@ -1010,7 +1044,7 @@ bool ETHClass::fullDuplex() const {
10101044
return (link_duplex == ETH_DUPLEX_FULL);
10111045
}
10121046

1013-
bool ETHClass::setFullDuplex(bool on) {
1047+
bool ETHClass::_setFullDuplex(bool on) {
10141048
if (_eth_handle == NULL) {
10151049
return false;
10161050
}
@@ -1022,6 +1056,18 @@ bool ETHClass::setFullDuplex(bool on) {
10221056
return err == ESP_OK;
10231057
}
10241058

1059+
bool ETHClass::setFullDuplex(bool on) {
1060+
if (_eth_started) {
1061+
log_e("This method must be called before ETH.begin()");
1062+
return false;
1063+
}
1064+
if (_auto_negotiation) {
1065+
log_w("Auto Negotiation MUST be OFF for this setting to be applied");
1066+
}
1067+
_full_duplex = on;
1068+
return true;
1069+
}
1070+
10251071
bool ETHClass::autoNegotiation() const {
10261072
if (_eth_handle == NULL) {
10271073
return false;
@@ -1031,7 +1077,7 @@ bool ETHClass::autoNegotiation() const {
10311077
return auto_nego;
10321078
}
10331079

1034-
bool ETHClass::setAutoNegotiation(bool on) {
1080+
bool ETHClass::_setAutoNegotiation(bool on) {
10351081
if (_eth_handle == NULL) {
10361082
return false;
10371083
}
@@ -1042,6 +1088,15 @@ bool ETHClass::setAutoNegotiation(bool on) {
10421088
return err == ESP_OK;
10431089
}
10441090

1091+
bool ETHClass::setAutoNegotiation(bool on) {
1092+
if (_eth_started) {
1093+
log_e("This method must be called before ETH.begin()");
1094+
return false;
1095+
}
1096+
_auto_negotiation = on;
1097+
return true;
1098+
}
1099+
10451100
uint32_t ETHClass::phyAddr() const {
10461101
if (_eth_handle == NULL) {
10471102
return 0;
@@ -1060,7 +1115,7 @@ uint16_t ETHClass::linkSpeed() const {
10601115
return (link_speed == ETH_SPEED_10M) ? 10 : 100;
10611116
}
10621117

1063-
bool ETHClass::setLinkSpeed(uint16_t speed) {
1118+
bool ETHClass::_setLinkSpeed(uint16_t speed) {
10641119
if (_eth_handle == NULL) {
10651120
return false;
10661121
}
@@ -1072,6 +1127,22 @@ bool ETHClass::setLinkSpeed(uint16_t speed) {
10721127
return err == ESP_OK;
10731128
}
10741129

1130+
bool ETHClass::setLinkSpeed(uint16_t speed) {
1131+
if (speed != 10 && speed != 100) {
1132+
log_e("Ethernet currently supports only 10 or 100 Mbps link speed");
1133+
return false;
1134+
}
1135+
if (_eth_started) {
1136+
log_e("This method must be called before ETH.begin()");
1137+
return false;
1138+
}
1139+
if (_auto_negotiation) {
1140+
log_w("Auto Negotiation MUST be OFF for this setting to be applied");
1141+
}
1142+
_link_speed = speed;
1143+
return true;
1144+
}
1145+
10751146
// void ETHClass::getMac(uint8_t* mac)
10761147
// {
10771148
// if(_eth_handle != NULL && mac != NULL){

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

+7
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ class ETHClass : public NetworkInterface {
229229
esp_eth_netif_glue_handle_t _glue_handle;
230230
esp_eth_mac_t *_mac;
231231
esp_eth_phy_t *_phy;
232+
bool _eth_started;
233+
uint16_t _link_speed;
234+
bool _full_duplex;
235+
bool _auto_negotiation;
232236
#if ETH_SPI_SUPPORTS_CUSTOM
233237
SPIClass *_spi;
234238
char _cs_str[10];
@@ -257,6 +261,9 @@ class ETHClass : public NetworkInterface {
257261
#endif
258262
int sck, int miso, int mosi, spi_host_device_t spi_host, uint8_t spi_freq_mhz
259263
);
264+
bool _setFullDuplex(bool on);
265+
bool _setLinkSpeed(uint16_t speed);
266+
bool _setAutoNegotiation(bool on);
260267

261268
friend class EthernetClass; // to access beginSPI
262269
};

0 commit comments

Comments
 (0)