mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
feat(esp_eth): add ESP32-S31 EMAC support
Add internal EMAC support for ESP32-S31, including: - HAL/LL layer: emac_ll, emac_hal, emac_clk, emac_periph for S31 - SOC layer: register structs, soc_caps, peripherals linker script, interrupt definitions - MAC driver: clock source configuration via Kconfig, GPIO/DMA adaptations, PHY register defs for clause-45 MDIO - Ethernet examples updated for S31 (basic, build-test-rules, PTP readme) - Refactored existing ESP32/ESP32-P4 EMAC code for shared patterns (emac_clk extraction, struct alignment, periph descriptor cleanup)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -226,6 +226,8 @@ esp_err_t esp_eth_phy_802_3_updt_link_dup_spd(phy_802_3_t *phy_802_3)
|
||||
bmsr_reg_t bmsr;
|
||||
anar_reg_t anar;
|
||||
anlpar_reg_t anlpar;
|
||||
gbcr_reg_t gbcr;
|
||||
gbsr_reg_t gbsr;
|
||||
|
||||
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed");
|
||||
eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
|
||||
@@ -237,26 +239,49 @@ esp_err_t esp_eth_phy_802_3_updt_link_dup_spd(phy_802_3_t *phy_802_3)
|
||||
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_ANAR_REG_ADDR, &(anar.val)), err, TAG, "read ANAR failed");
|
||||
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)), err, TAG, "read ANLPAR failed");
|
||||
if (bmcr.en_auto_nego) {
|
||||
if (anar.base100_tx_fd && anlpar.base100_tx_fd) {
|
||||
speed = ETH_SPEED_100M;
|
||||
duplex = ETH_DUPLEX_FULL;
|
||||
} else if (anar.base100_tx && anlpar.base100_tx) {
|
||||
speed = ETH_SPEED_100M;
|
||||
duplex = ETH_DUPLEX_HALF;
|
||||
} else if (anar.base10_t_fd && anlpar.base10_t_fd) {
|
||||
speed = ETH_SPEED_10M;
|
||||
duplex = ETH_DUPLEX_FULL;
|
||||
} else if (anar.base10_t && anlpar.base10_t) {
|
||||
speed = ETH_SPEED_10M;
|
||||
duplex = ETH_DUPLEX_HALF;
|
||||
} else {
|
||||
ESP_GOTO_ON_FALSE(false, ESP_FAIL, err, TAG, "invalid auto-nego speed/duplex advertising");
|
||||
bool need_anar_mode = false;
|
||||
if (bmsr.ext_status) {
|
||||
if (eth->phy_reg_read(eth, addr, ETH_PHY_GBCR_REG_ADDR, &(gbcr.val)) == ESP_OK &&
|
||||
eth->phy_reg_read(eth, addr, ETH_PHY_GBSR_REG_ADDR, &(gbsr.val)) == ESP_OK) {
|
||||
if (gbcr.base1000_t_fd && gbsr.lp_base1000_t_fd) {
|
||||
speed = ETH_SPEED_1000M;
|
||||
duplex = ETH_DUPLEX_FULL;
|
||||
} else if (gbcr.base1000_t && gbsr.lp_base1000_t) {
|
||||
speed = ETH_SPEED_1000M;
|
||||
duplex = ETH_DUPLEX_HALF;
|
||||
} else {
|
||||
need_anar_mode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bmsr.ext_status || need_anar_mode) {
|
||||
bool mode_valid = true;
|
||||
if (anar.base100_tx_fd && anlpar.base100_tx_fd) {
|
||||
speed = ETH_SPEED_100M;
|
||||
duplex = ETH_DUPLEX_FULL;
|
||||
} else if (anar.base100_tx && anlpar.base100_tx) {
|
||||
speed = ETH_SPEED_100M;
|
||||
duplex = ETH_DUPLEX_HALF;
|
||||
} else if (anar.base10_t_fd && anlpar.base10_t_fd) {
|
||||
speed = ETH_SPEED_10M;
|
||||
duplex = ETH_DUPLEX_FULL;
|
||||
} else if (anar.base10_t && anlpar.base10_t) {
|
||||
speed = ETH_SPEED_10M;
|
||||
duplex = ETH_DUPLEX_HALF;
|
||||
} else {
|
||||
mode_valid = false;
|
||||
}
|
||||
ESP_GOTO_ON_FALSE(mode_valid, ESP_FAIL, err, TAG, "invalid auto-nego speed/duplex advertising");
|
||||
}
|
||||
} else {
|
||||
speed = bmcr.speed_select ? ETH_SPEED_100M : ETH_SPEED_10M;
|
||||
if (bmcr.speed_1000) {
|
||||
speed = ETH_SPEED_1000M;
|
||||
} else {
|
||||
speed = bmcr.speed_select ? ETH_SPEED_100M : ETH_SPEED_10M;
|
||||
}
|
||||
duplex = bmcr.duplex_mode ? ETH_DUPLEX_FULL : ETH_DUPLEX_HALF;
|
||||
}
|
||||
|
||||
ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_SPEED, (void *)speed), err, TAG, "change speed failed");
|
||||
ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_DUPLEX, (void *)duplex), err, TAG, "change duplex failed");
|
||||
/* if we're in duplex mode, and peer has the flow control ability */
|
||||
@@ -375,7 +400,13 @@ esp_err_t esp_eth_phy_802_3_set_speed(phy_802_3_t *phy_802_3, eth_speed_t speed)
|
||||
/* Set speed */
|
||||
bmcr_reg_t bmcr;
|
||||
ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, phy_802_3->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
|
||||
bmcr.speed_select = speed == ETH_SPEED_100M ? 1 : 0;
|
||||
if (speed == ETH_SPEED_1000M) {
|
||||
bmcr.speed_1000 = 1;
|
||||
bmcr.speed_select = 0;
|
||||
} else {
|
||||
bmcr.speed_1000 = 0;
|
||||
bmcr.speed_select = speed == ETH_SPEED_100M ? 1 : 0;
|
||||
}
|
||||
ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, phy_802_3->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val), err, TAG, "write BMCR failed");
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
Reference in New Issue
Block a user