[Ethernet] ksz8081rna support (#4739)

Co-authored-by: Your Name <you@example.com>
This commit is contained in:
Fabian 2023-07-10 00:02:42 +02:00 committed by GitHub
parent 8739552c0b
commit 8bf8892ab3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 1 deletions

View file

@ -35,6 +35,7 @@ ETHERNET_TYPES = {
"IP101": EthernetType.ETHERNET_TYPE_IP101,
"JL1101": EthernetType.ETHERNET_TYPE_JL1101,
"KSZ8081": EthernetType.ETHERNET_TYPE_KSZ8081,
"KSZ8081RNA": EthernetType.ETHERNET_TYPE_KSZ8081RNA,
}
emac_rmii_clock_mode_t = cg.global_ns.enum("emac_rmii_clock_mode_t")

View file

@ -84,7 +84,8 @@ void EthernetComponent::setup() {
this->phy_ = esp_eth_phy_new_jl1101(&phy_config);
break;
}
case ETHERNET_TYPE_KSZ8081: {
case ETHERNET_TYPE_KSZ8081:
case ETHERNET_TYPE_KSZ8081RNA: {
#if ESP_IDF_VERSION_MAJOR >= 5
this->phy_ = esp_eth_phy_new_ksz80xx(&phy_config);
#else
@ -102,6 +103,12 @@ void EthernetComponent::setup() {
this->eth_handle_ = nullptr;
err = esp_eth_driver_install(&eth_config, &this->eth_handle_);
ESPHL_ERROR_CHECK(err, "ETH driver install error");
if (this->type_ == ETHERNET_TYPE_KSZ8081RNA && this->clk_mode_ == EMAC_CLK_OUT) {
// KSZ8081RNA default is incorrect. It expects a 25MHz clock instead of the 50MHz we provide.
this->ksz8081_set_clock_reference_(mac);
}
/* attach Ethernet driver to TCP/IP stack */
err = esp_netif_attach(this->eth_netif_, esp_eth_new_netif_glue(this->eth_handle_));
ESPHL_ERROR_CHECK(err, "ETH netif attach error");
@ -184,6 +191,10 @@ void EthernetComponent::dump_config() {
eth_type = "KSZ8081";
break;
case ETHERNET_TYPE_KSZ8081RNA:
eth_type = "KSZ8081RNA";
break;
default:
eth_type = "Unknown";
break;
@ -385,6 +396,37 @@ bool EthernetComponent::powerdown() {
return true;
}
void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) {
#define KSZ80XX_PC2R_REG_ADDR (0x1F)
esp_err_t err;
uint32_t phy_control_2;
err = mac->read_phy_reg(mac, this->phy_addr_, KSZ80XX_PC2R_REG_ADDR, &(phy_control_2));
ESPHL_ERROR_CHECK(err, "Read PHY Control 2 failed");
ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty((u_int8_t *) &phy_control_2, 2).c_str());
/*
* Bit 7 is `RMII Reference Clock Select`. Default is `0`.
* KSZ8081RNA:
* 0 - clock input to XI (Pin 8) is 25 MHz for RMII 25 MHz clock mode.
* 1 - clock input to XI (Pin 8) is 50 MHz for RMII 50 MHz clock mode.
* KSZ8081RND:
* 0 - clock input to XI (Pin 8) is 50 MHz for RMII 50 MHz clock mode.
* 1 - clock input to XI (Pin 8) is 25 MHz (driven clock only, not a crystal) for RMII 25 MHz clock mode.
*/
if ((phy_control_2 & (1 << 7)) != (1 << 7)) {
phy_control_2 |= 1 << 7;
err = mac->write_phy_reg(mac, this->phy_addr_, KSZ80XX_PC2R_REG_ADDR, phy_control_2);
ESPHL_ERROR_CHECK(err, "Write PHY Control 2 failed");
err = mac->read_phy_reg(mac, this->phy_addr_, KSZ80XX_PC2R_REG_ADDR, &(phy_control_2));
ESPHL_ERROR_CHECK(err, "Read PHY Control 2 failed");
ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty((u_int8_t *) &phy_control_2, 2).c_str());
}
#undef KSZ80XX_PC2R_REG_ADDR
}
} // namespace ethernet
} // namespace esphome

View file

@ -21,6 +21,7 @@ enum EthernetType {
ETHERNET_TYPE_IP101,
ETHERNET_TYPE_JL1101,
ETHERNET_TYPE_KSZ8081,
ETHERNET_TYPE_KSZ8081RNA,
};
struct ManualIP {
@ -67,6 +68,8 @@ class EthernetComponent : public Component {
void start_connect_();
void dump_connect_params_();
/// @brief Set `RMII Reference Clock Select` bit for KSZ8081.
void ksz8081_set_clock_reference_(esp_eth_mac_t *mac);
std::string use_address_;
uint8_t phy_addr_{0};