diff --git a/components/esp_eth/CMakeLists.txt b/components/esp_eth/CMakeLists.txt index 894966d34e..b76d035ded 100644 --- a/components/esp_eth/CMakeLists.txt +++ b/components/esp_eth/CMakeLists.txt @@ -1,34 +1,30 @@ -set(srcs) # If ethernet disabled in Kconfig, this is a config-only component +set(srcs) set(include) -set(linker) +# If Ethernet disabled in Kconfig, this is a config-only component if(CONFIG_ETH_ENABLED) set(srcs "src/esp_eth.c") set(include "include") - set(linker "linker.lf") if(CONFIG_ETH_USE_ESP32_EMAC) list(APPEND srcs "src/esp_eth_mac_esp32.c" - "src/esp_eth_phy_dp83848.c" - "src/esp_eth_phy_ip101.c" - "src/esp_eth_phy_lan8720.c" - "src/esp_eth_phy_rtl8201.c" - ) + "src/esp_eth_phy_dp83848.c" + "src/esp_eth_phy_ip101.c" + "src/esp_eth_phy_lan8720.c" + "src/esp_eth_phy_rtl8201.c") endif() if(CONFIG_ETH_SPI_ETHERNET_DM9051) list(APPEND srcs "src/esp_eth_mac_dm9051.c" - "src/esp_eth_phy_dm9051.c") + "src/esp_eth_phy_dm9051.c") + endif() + + if(CONFIG_ETH_USE_OPENETH) + list(APPEND srcs "src/esp_eth_mac_openeth.c") endif() endif() -if(CONFIG_ETH_USE_OPENETH) - list(APPEND srcs "src/esp_eth_mac_openeth.c") -endif() - idf_component_register(SRCS "${srcs}" - INCLUDE_DIRS ${include} - LDFRAGMENTS ${linker} - REQUIRES "esp_event" - PRIV_REQUIRES "esp_netif" "driver" "log") - + INCLUDE_DIRS ${include} + REQUIRES "esp_event" + PRIV_REQUIRES "esp_netif" "driver" "log") diff --git a/components/esp_eth/Kconfig b/components/esp_eth/Kconfig index 9988d995ed..b11b4a31b0 100644 --- a/components/esp_eth/Kconfig +++ b/components/esp_eth/Kconfig @@ -1,7 +1,6 @@ menu "Ethernet" - # Invisible item that is enabled if any Ethernet - # selection is made + # Invisible item that is enabled if any Ethernet selection is made config ETH_ENABLED bool @@ -81,36 +80,6 @@ menu "Ethernet" endif endif - config ETH_SMI_MDC_GPIO - int "SMI MDC GPIO number" - default 23 - range 0 33 - help - Set the GPIO number used by SMI MDC. - - config ETH_SMI_MDIO_GPIO - int "SMI MDIO GPIO number" - default 18 - range 0 33 - help - Set the GPIO number used by SMI MDIO. - - config ETH_PHY_USE_RST - bool "Use Reset Pin of PHY Chip" - default y - help - Set this option to true if you want to control PHY chip's reset using a GPIO. - Check the schematic of you board to make sure if it's necessary to use this feature. - - if ETH_PHY_USE_RST - config ETH_PHY_RST_GPIO - int "PHY RST GPIO number" - default 5 - range 0 33 - help - Set the GPIO number used by the PHY chip's RST pin. - endif - config ETH_DMA_BUFFER_SIZE int "Ethernet DMA buffer size (Byte)" range 256 1600 @@ -143,27 +112,19 @@ menu "Ethernet" ESP-IDF can also support some SPI-Ethernet modules. if ETH_USE_SPI_ETHERNET - menuconfig ETH_SPI_ETHERNET_DM9051 + config ETH_SPI_ETHERNET_DM9051 bool "Use DM9051" default y help DM9051 is a fast Ethernet controller with an SPI interface. It's also integrated with a 10/100M PHY and MAC. Set true to enable DM9051 driver. - - if ETH_SPI_ETHERNET_DM9051 - config ETH_DM9051_INT_GPIO - int "DM9051 Interrupt GPIO number" - default 4 - range 0 33 - help - Set the GPIO number used by DM9051's Interrupt pin. - endif endif menuconfig ETH_USE_OPENETH bool "Support OpenCores Ethernet MAC (for use with QEMU)" default n + select ETH_ENABLED help OpenCores Ethernet MAC driver can be used when an ESP-IDF application is executed in QEMU. This driver is not supported when running on a diff --git a/components/esp_eth/component.mk b/components/esp_eth/component.mk index 252aafccfe..65702f29fc 100644 --- a/components/esp_eth/component.mk +++ b/components/esp_eth/component.mk @@ -3,7 +3,6 @@ # COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_SRCDIRS := src -COMPONENT_ADD_LDFRAGMENTS += linker.lf ifndef CONFIG_ETH_USE_ESP32_EMAC COMPONENT_OBJEXCLUDE += src/esp_eth_mac_esp32.o diff --git a/components/esp_eth/include/esp_eth_mac.h b/components/esp_eth/include/esp_eth_mac.h index 70b475b0a9..5e083e34bf 100644 --- a/components/esp_eth/include/esp_eth_mac.h +++ b/components/esp_eth/include/esp_eth_mac.h @@ -22,7 +22,6 @@ extern "C" { #include "sdkconfig.h" #include "esp_eth_com.h" #if CONFIG_ETH_USE_SPI_ETHERNET -#include "driver/gpio.h" #include "driver/spi_master.h" #endif @@ -258,6 +257,8 @@ typedef struct { uint32_t sw_reset_timeout_ms; /*!< Software reset timeout value (Unit: ms) */ uint32_t rx_task_stack_size; /*!< Stack size of the receive task */ uint32_t rx_task_prio; /*!< Priority of the receive task */ + int smi_mdc_gpio_num; /*!< SMI MDC GPIO number */ + int smi_mdio_gpio_num; /*!< SMI MDIO GPIO number */ } eth_mac_config_t; /** @@ -269,6 +270,8 @@ typedef struct { .sw_reset_timeout_ms = 100, \ .rx_task_stack_size = 4096, \ .rx_task_prio = 15, \ + .smi_mdc_gpio_num = 23, \ + .smi_mdio_gpio_num = 18, \ } #if CONFIG_ETH_USE_ESP32_EMAC @@ -291,6 +294,7 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config); */ typedef struct { spi_device_handle_t spi_hdl; /*!< Handle of SPI device driver */ + int int_gpio_num; /*!< Interrupt GPIO number */ } eth_dm9051_config_t; /** @@ -300,6 +304,7 @@ typedef struct { #define ETH_DM9051_DEFAULT_CONFIG(spi_device) \ { \ .spi_hdl = spi_device, \ + .int_gpio_num = 4, \ } /** diff --git a/components/esp_eth/include/esp_eth_phy.h b/components/esp_eth/include/esp_eth_phy.h index 5a0080d5dc..f29b3096d8 100644 --- a/components/esp_eth/include/esp_eth_phy.h +++ b/components/esp_eth/include/esp_eth_phy.h @@ -53,7 +53,7 @@ struct esp_eth_phy_s { esp_err_t (*set_mediator)(esp_eth_phy_t *phy, esp_eth_mediator_t *mediator); /** - * @brief Reset Ethernet PHY + * @brief Software Reset Ethernet PHY * * @param[in] phy: Ethernet PHY instance * @@ -64,6 +64,20 @@ struct esp_eth_phy_s { */ esp_err_t (*reset)(esp_eth_phy_t *phy); + /** + * @brief Hardware Reset Ethernet PHY + * + * @note Hardware reset is mostly done by pull down and up PHY's nRST pin + * + * @param[in] phy: Ethernet PHY instance + * + * @return + * - ESP_OK: reset Ethernet PHY successfully + * - ESP_FAIL: reset Ethernet PHY failed because some error occurred + * + */ + esp_err_t (*reset_hw)(esp_eth_phy_t *phy); + /** * @brief Initialize Ethernet PHY * @@ -172,17 +186,19 @@ typedef struct { uint32_t phy_addr; /*!< PHY address */ uint32_t reset_timeout_ms; /*!< Reset timeout value (Unit: ms) */ uint32_t autonego_timeout_ms; /*!< Auto-negotiation timeout value (Unit: ms) */ + int reset_gpio_num; /*!< Reset GPIO number, -1 means no hardware reset */ } eth_phy_config_t; /** * @brief Default configuration for Ethernet PHY object * */ -#define ETH_PHY_DEFAULT_CONFIG() \ - { \ - .phy_addr = 1, \ - .reset_timeout_ms = 100, \ - .autonego_timeout_ms = 4000 \ +#define ETH_PHY_DEFAULT_CONFIG() \ + { \ + .phy_addr = 1, \ + .reset_timeout_ms = 100, \ + .autonego_timeout_ms = 4000, \ + .reset_gpio_num = 5, \ } /** diff --git a/components/esp_eth/linker.lf b/components/esp_eth/linker.lf deleted file mode 100644 index 64969708d9..0000000000 --- a/components/esp_eth/linker.lf +++ /dev/null @@ -1,12 +0,0 @@ -[mapping:esp_eth] -archive: libesp_eth.a -entries: - if ETH_USE_ESP32_EMAC = y: - esp_eth_mac_esp32:emac_hal_tx_complete_cb (noflash_text) - esp_eth_mac_esp32:emac_hal_tx_unavail_cb (noflash_text) - esp_eth_mac_esp32:emac_hal_rx_complete_cb (noflash_text) - esp_eth_mac_esp32:emac_hal_rx_early_cb (noflash_text) - esp_eth_mac_esp32:emac_hal_rx_unavail_cb (noflash_text) - esp_eth_mac_esp32:emac_esp32_isr_handler (noflash_text) - if ETH_SPI_ETHERNET_DM9051 = y: - esp_eth_mac_dm9051:dm9051_isr_handler (noflash_text) diff --git a/components/esp_eth/src/dm9051.h b/components/esp_eth/src/dm9051.h new file mode 100644 index 0000000000..acc855dec3 --- /dev/null +++ b/components/esp_eth/src/dm9051.h @@ -0,0 +1,162 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Registers in DM9051 + * + */ +#define DM9051_NCR (0x00) // Network Control Register +#define DM9051_NSR (0x01) // Network Status Register +#define DM9051_TCR (0x02) // Tx Control Register +#define DM9051_TSR1 (0x03) // Tx Status Register I +#define DM9051_TSR2 (0x04) // Tx Status Register II +#define DM9051_RCR (0x05) // Rx Control Register +#define DM9051_RSR (0x06) // Rx Status Register +#define DM9051_ROCR (0x07) // Receive Overflow Counter Register +#define DM9051_BPTR (0x08) // Back Pressure Threshold Register +#define DM9051_FCTR (0x09) // Flow Control Threshold Register +#define DM9051_FCR (0x0A) // Rx/Tx Flow Control Register +#define DM9051_EPCR (0x0B) // EEPROM & PHY Control Register +#define DM9051_EPAR (0x0C) // EEPROM & PHY Address Register +#define DM9051_EPDRL (0x0D) // EEPROM & PHY Data Register Low +#define DM9051_EPDRH (0x0E) // EEPROM & PHY Data Register High +#define DM9051_WCR (0x0F) // Wake Up Control Register +#define DM9051_PAR (0x10) // Physical Address Register +#define DM9051_MAR (0x16) // Multicast Address Hash Table Register +#define DM9051_GPCR (0x1E) // General Purpose Control Register +#define DM9051_GPR (0x1F) // General Purpose Register +#define DM9051_TRPAL (0x22) // Tx Memory Read Pointer Address Low Byte +#define DM9051_TRPAH (0x23) // Tx Memory Read Pointer Address High Byte +#define DM9051_RWPAL (0x24) // Rx Memory Read Pointer Address Low Byte +#define DM9051_RWPAH (0x25) // Rx Memory Read Pointer Address High Byte +#define DM9051_VIDL (0x28) // Vendor ID Low Byte +#define DM9051_VIDH (0x29) // Vendor ID High Byte +#define DM9051_PIDL (0x2A) // Product ID Low Byte +#define DM9051_PIDH (0x2B) // Product ID High Byte +#define DM9051_CHIPR (0x2C) // CHIP Revision +#define DM9051_TCR2 (0x2D) // Transmit Control Register 2 +#define DM9051_ATCR (0x30) // Auto-Transmit Control Register +#define DM9051_TCSCR (0x31) // Transmit Check Sum Control Register +#define DM9051_RCSCSR (0x32) // Receive Check Sum Control Status Register +#define DM9051_SBCR (0x38) // SPI Bus Control Register +#define DM9051_INTCR (0x39) // INT Pin Control Register +#define DM9051_PPCSR (0x3D) // Pause Packet Control Status Register +#define DM9051_EEE_IN (0x3E) // IEEE 802.3az Enter Counter Register +#define DM9051_EEE_OUT (0x3F) // IEEE 802.3az Leave Counter Register +#define DM9051_ALNCR (0x4A) // SPI Byte Align Error Counter Register +#define DM9051_RLENCR (0x52) // Rx Packet Length Control Register +#define DM9051_BCASTCR (0x53) // RX Broadcast Control Register +#define DM9051_INTCKCR (0x54) // INT Pin Clock Output Control Register +#define DM9051_MPTRCR (0x55) // Memory Pointer Control Register +#define DM9051_MLEDCR (0x57) // More LED Control Register +#define DM9051_MEMSCR (0x59) // Memory Control Register +#define DM9051_TMEMR (0x5A) // Transmit Memory Size Register +#define DM9051_MBSR (0x5D) // Memory BIST Status Register +#define DM9051_MRCMDX (0x70) // Memory Data Pre-Fetch Read Command Without Address Increment Register +#define DM9051_MRCMDX1 (0x71) // Memory Read Command Without Pre-Fetch and Without Address Increment Register +#define DM9051_MRCMD (0x72) // Memory Data Read Command With Address Increment Register +#define DM9051_SDR_DLY (0x73) // SPI Data Read Delay Counter Register +#define DM9051_MRRL (0x74) // Memory Data Read Address Register Low Byte +#define DM9051_MRRH (0x75) // Memory Data Read Address Register High Byte +#define DM9051_MWCMDX (0x76) // Memory Data Write Command Without Address Increment Register +#define DM9051_MWCMD (0x78) // Memory Data Write Command With Address Increment Register +#define DM9051_MWRL (0x7A) // Memory Data Write Address Register Low Byte +#define DM9051_MWRH (0x7B) // Memory Data Write Address Register High Byte +#define DM9051_TXPLL (0x7C) // TX Packet Length Low Byte Register +#define DM9051_TXPLH (0x7D) // TX Packet Length High Byte Register +#define DM9051_ISR (0x7E) // Interrupt Status Register +#define DM9051_IMR (0x7F) // Interrupt Mask Register + +/** + * @brief status and flag of DM9051 specific registers + * + */ +#define DM9051_SPI_RD (0) // Burst Read Command +#define DM9051_SPI_WR (1) // Burst Write Command + +#define NCR_WAKEEN (1 << 6) // Enable Wakeup Function +#define NCR_FDX (1 << 3) // Duplex Mode of the Internal PHY +#define NCR_RST (1 << 0) // Software Reset and Auto-Clear after 10us + +#define NSR_SPEED (1 << 7) // Speed of Internal PHY +#define NSR_LINKST (1 << 6) // Link Status of Internal PHY +#define NSR_WAKEST (1 << 5) // Wakeup Event Status +#define NSR_TX2END (1 << 3) // TX Packet Index II Complete Status +#define NSR_TX1END (1 << 2) // TX Packet Index I Complete Status +#define NSR_RXOV (1 << 1) // RX Memory Overflow Status +#define NSR_RXRDY (1 << 0) // RX Packet Ready + +#define TCR_TXREQ (1 << 0) // TX Request. Auto-Clear after Sending Completely + +#define RCR_WTDIS (1 << 6) // Watchdog Timer Disable +#define RCR_DIS_LONG (1 << 5) // Discard Long Packet +#define RCR_DIS_CRC (1 << 4) // Discard CRC Error Packet +#define RCR_ALL (1 << 3) // Receive All Multicast +#define RCR_RUNT (1 << 2) // Receive Runt Packet +#define RCR_PRMSC (1 << 1) // Promiscuous Mode +#define RCR_RXEN (1 << 0) // RX Enable + +#define RSR_RF (1 << 7) // Runt Frame +#define RSR_MF (1 << 6) // Multicast Frame +#define RSR_LCS (1 << 5) // Late Collision Seen +#define RSR_RWTO (1 << 4) // Receive Watchdog Time-Out +#define RSR_PLE (1 << 3) // Physical Layer Error +#define RSR_AE (1 << 2) // Alignment Error +#define RSR_CE (1 << 1) // CRC Error +#define RSR_FOE (1 << 0) // RX Memory Overflow Error + +#define FCR_FLOW_ENABLE (0x39) // Enable Flow Control + +#define EPCR_REEP (1 << 5) // Reload EEPROM +#define EPCR_WEP (1 << 4) // Write EEPROM Enable +#define EPCR_EPOS (1 << 3) // EEPROM or PHY Operation Select +#define EPCR_ERPRR (1 << 2) // EEPROM Read or PHY Register Read Command +#define EPCR_ERPRW (1 << 1) // EEPROM Write or PHY Register Write Command +#define EPCR_ERRE (1 << 0) // EEPROM Access Status or PHY Access Status + +#define TCR2_RLCP (1 << 6) // Retry Late Collision Packet + +#define ATCR_AUTO_TX (1 << 7) // Auto-Transmit Control + +#define TCSCR_UDPCSE (1 << 2) // UDP CheckSum Generation +#define TCSCR_TCPCSE (1 << 1) // TCP CheckSum Generation +#define TCSCR_IPCSE (1 << 0) // IPv4 CheckSum Generation + +#define MPTRCR_RST_TX (1 << 1) // Reset TX Memory Pointer +#define MPTRCR_RST_RX (1 << 0) // Reset RX Memory Pointer + +#define ISR_LNKCHGS (1 << 5) // Link Status Change +#define ISR_ROO (1 << 3) // Receive Overflow Counter Overflow +#define ISR_ROS (1 << 2) // Receive Overflow +#define ISR_PT (1 << 1) // Packet Transmitted +#define ISR_PR (1 << 0) // Packet Received +#define ISR_CLR_STATUS (ISR_LNKCHGS | ISR_ROO | ISR_ROS | ISR_PT | ISR_PR) + +#define IMR_PAR (1 << 7) // Pointer Auto-Return Mode +#define IMR_LNKCHGI (1 << 5) // Enable Link Status Change Interrupt +#define IMR_ROOI (1 << 3) // Enable Receive Overflow Counter Overflow Interrupt +#define IMR_ROI (1 << 2) // Enable Receive Overflow Interrupt +#define IMR_PTI (1 << 1) // Enable Packet Transmitted Interrupt +#define IMR_PRI (1 << 0) // Enable Packet Received Interrupt +#define IMR_ALL (IMR_PAR | IMR_LNKCHGI | IMR_ROOI | IMR_ROI | IMR_PTI | IMR_PRI) + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_eth/src/esp_eth.c b/components/esp_eth/src/esp_eth.c index c583d7a85b..a5119db650 100644 --- a/components/esp_eth/src/esp_eth.c +++ b/components/esp_eth/src/esp_eth.c @@ -226,6 +226,8 @@ esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_ eth_driver->mediator.phy_reg_write = eth_phy_reg_write; eth_driver->mediator.stack_input = eth_stack_input; eth_driver->mediator.on_state_changed = eth_on_state_changed; + /* some PHY can't output RMII clock if in reset state, so hardware reset PHY chip firstly */ + phy->reset_hw(phy); ETH_CHECK(mac->set_mediator(mac, ð_driver->mediator) == ESP_OK, "set mediator for mac failed", err_mediator, ESP_FAIL); ETH_CHECK(phy->set_mediator(phy, ð_driver->mediator) == ESP_OK, "set mediator for phy failed", err_mediator, ESP_FAIL); ETH_CHECK(mac->init(mac) == ESP_OK, "init mac failed", err_init_mac, ESP_FAIL); diff --git a/components/esp_eth/src/esp_eth_mac_dm9051.c b/components/esp_eth/src/esp_eth_mac_dm9051.c index b1dfadd30c..625cbdd6c4 100644 --- a/components/esp_eth/src/esp_eth_mac_dm9051.c +++ b/components/esp_eth/src/esp_eth_mac_dm9051.c @@ -16,6 +16,7 @@ #include #include "driver/gpio.h" #include "driver/spi_master.h" +#include "esp_attr.h" #include "esp_log.h" #include "esp_eth.h" #include "esp_system.h" @@ -24,6 +25,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" +#include "dm9051.h" #include "sdkconfig.h" static const char *TAG = "emac_dm9051"; @@ -41,145 +43,6 @@ static const char *TAG = "emac_dm9051"; #define DM9051_SPI_LOCK_TIMEOUT_MS (50) #define DM9051_PHY_OPERATION_TIMEOUT_US (1000) -/** - * @brief Registers in DM9051 - * - */ -#define DM9051_NCR (0x00) // Network Control Register -#define DM9051_NSR (0x01) // Network Status Register -#define DM9051_TCR (0x02) // Tx Control Register -#define DM9051_TSR1 (0x03) // Tx Status Register I -#define DM9051_TSR2 (0x04) // Tx Status Register II -#define DM9051_RCR (0x05) // Rx Control Register -#define DM9051_RSR (0x06) // Rx Status Register -#define DM9051_ROCR (0x07) // Receive Overflow Counter Register -#define DM9051_BPTR (0x08) // Back Pressure Threshold Register -#define DM9051_FCTR (0x09) // Flow Control Threshold Register -#define DM9051_FCR (0x0A) // Rx/Tx Flow Control Register -#define DM9051_EPCR (0x0B) // EEPROM & PHY Control Register -#define DM9051_EPAR (0x0C) // EEPROM & PHY Address Register -#define DM9051_EPDRL (0x0D) // EEPROM & PHY Data Register Low -#define DM9051_EPDRH (0x0E) // EEPROM & PHY Data Register High -#define DM9051_WCR (0x0F) // Wake Up Control Register -#define DM9051_PAR (0x10) // Physical Address Register -#define DM9051_MAR (0x16) // Multicast Address Hash Table Register -#define DM9051_GPCR (0x1E) // General Purpose Control Register -#define DM9051_GPR (0x1F) // General Purpose Register -#define DM9051_TRPAL (0x22) // Tx Memory Read Pointer Address Low Byte -#define DM9051_TRPAH (0x23) // Tx Memory Read Pointer Address High Byte -#define DM9051_RWPAL (0x24) // Rx Memory Read Pointer Address Low Byte -#define DM9051_RWPAH (0x25) // Rx Memory Read Pointer Address High Byte -#define DM9051_VIDL (0x28) // Vendor ID Low Byte -#define DM9051_VIDH (0x29) // Vendor ID High Byte -#define DM9051_PIDL (0x2A) // Product ID Low Byte -#define DM9051_PIDH (0x2B) // Product ID High Byte -#define DM9051_CHIPR (0x2C) // CHIP Revision -#define DM9051_TCR2 (0x2D) // Transmit Control Register 2 -#define DM9051_ATCR (0x30) // Auto-Transmit Control Register -#define DM9051_TCSCR (0x31) // Transmit Check Sum Control Register -#define DM9051_RCSCSR (0x32) // Receive Check Sum Control Status Register -#define DM9051_SBCR (0x38) // SPI Bus Control Register -#define DM9051_INTCR (0x39) // INT Pin Control Register -#define DM9051_PPCSR (0x3D) // Pause Packet Control Status Register -#define DM9051_EEE_IN (0x3E) // IEEE 802.3az Enter Counter Register -#define DM9051_EEE_OUT (0x3F) // IEEE 802.3az Leave Counter Register -#define DM9051_ALNCR (0x4A) // SPI Byte Align Error Counter Register -#define DM9051_RLENCR (0x52) // Rx Packet Length Control Register -#define DM9051_BCASTCR (0x53) // RX Broadcast Control Register -#define DM9051_INTCKCR (0x54) // INT Pin Clock Output Control Register -#define DM9051_MPTRCR (0x55) // Memory Pointer Control Register -#define DM9051_MLEDCR (0x57) // More LED Control Register -#define DM9051_MEMSCR (0x59) // Memory Control Register -#define DM9051_TMEMR (0x5A) // Transmit Memory Size Register -#define DM9051_MBSR (0x5D) // Memory BIST Status Register -#define DM9051_MRCMDX (0x70) // Memory Data Pre-Fetch Read Command Without Address Increment Register -#define DM9051_MRCMDX1 (0x71) // Memory Read Command Without Pre-Fetch and Without Address Increment Register -#define DM9051_MRCMD (0x72) // Memory Data Read Command With Address Increment Register -#define DM9051_SDR_DLY (0x73) // SPI Data Read Delay Counter Register -#define DM9051_MRRL (0x74) // Memory Data Read Address Register Low Byte -#define DM9051_MRRH (0x75) // Memory Data Read Address Register High Byte -#define DM9051_MWCMDX (0x76) // Memory Data Write Command Without Address Increment Register -#define DM9051_MWCMD (0x78) // Memory Data Write Command With Address Increment Register -#define DM9051_MWRL (0x7A) // Memory Data Write Address Register Low Byte -#define DM9051_MWRH (0x7B) // Memory Data Write Address Register High Byte -#define DM9051_TXPLL (0x7C) // TX Packet Length Low Byte Register -#define DM9051_TXPLH (0x7D) // TX Packet Length High Byte Register -#define DM9051_ISR (0x7E) // Interrupt Status Register -#define DM9051_IMR (0x7F) // Interrupt Mask Register - -/** - * @brief status and flag of DM9051 specific registers - * - */ -#define DM9051_SPI_RD (0) // Burst Read Command -#define DM9051_SPI_WR (1) // Burst Write Command - -#define NCR_WAKEEN (1 << 6) // Enable Wakeup Function -#define NCR_FDX (1 << 3) // Duplex Mode of the Internal PHY -#define NCR_RST (1 << 0) // Software Reset and Auto-Clear after 10us - -#define NSR_SPEED (1 << 7) // Speed of Internal PHY -#define NSR_LINKST (1 << 6) // Link Status of Internal PHY -#define NSR_WAKEST (1 << 5) // Wakeup Event Status -#define NSR_TX2END (1 << 3) // TX Packet Index II Complete Status -#define NSR_TX1END (1 << 2) // TX Packet Index I Complete Status -#define NSR_RXOV (1 << 1) // RX Memory Overflow Status -#define NSR_RXRDY (1 << 0) // RX Packet Ready - -#define TCR_TXREQ (1 << 0) // TX Request. Auto-Clear after Sending Completely - -#define RCR_WTDIS (1 << 6) // Watchdog Timer Disable -#define RCR_DIS_LONG (1 << 5) // Discard Long Packet -#define RCR_DIS_CRC (1 << 4) // Discard CRC Error Packet -#define RCR_ALL (1 << 3) // Receive All Multicast -#define RCR_RUNT (1 << 2) // Receive Runt Packet -#define RCR_PRMSC (1 << 1) // Promiscuous Mode -#define RCR_RXEN (1 << 0) // RX Enable - -#define RSR_RF (1 << 7) // Runt Frame -#define RSR_MF (1 << 6) // Multicast Frame -#define RSR_LCS (1 << 5) // Late Collision Seen -#define RSR_RWTO (1 << 4) // Receive Watchdog Time-Out -#define RSR_PLE (1 << 3) // Physical Layer Error -#define RSR_AE (1 << 2) // Alignment Error -#define RSR_CE (1 << 1) // CRC Error -#define RSR_FOE (1 << 0) // RX Memory Overflow Error - -#define FCR_FLOW_ENABLE (0x39) // Enable Flow Control - -#define EPCR_REEP (1 << 5) // Reload EEPROM -#define EPCR_WEP (1 << 4) // Write EEPROM Enable -#define EPCR_EPOS (1 << 3) // EEPROM or PHY Operation Select -#define EPCR_ERPRR (1 << 2) // EEPROM Read or PHY Register Read Command -#define EPCR_ERPRW (1 << 1) // EEPROM Write or PHY Register Write Command -#define EPCR_ERRE (1 << 0) // EEPROM Access Status or PHY Access Status - -#define TCR2_RLCP (1 << 6) // Retry Late Collision Packet - -#define ATCR_AUTO_TX (1 << 7) // Auto-Transmit Control - -#define TCSCR_UDPCSE (1 << 2) // UDP CheckSum Generation -#define TCSCR_TCPCSE (1 << 1) // TCP CheckSum Generation -#define TCSCR_IPCSE (1 << 0) // IPv4 CheckSum Generation - -#define MPTRCR_RST_TX (1 << 1) // Reset TX Memory Pointer -#define MPTRCR_RST_RX (1 << 0) // Reset RX Memory Pointer - -#define ISR_LNKCHGS (1 << 5) // Link Status Change -#define ISR_ROO (1 << 3) // Receive Overflow Counter Overflow -#define ISR_ROS (1 << 2) // Receive Overflow -#define ISR_PT (1 << 1) // Packet Transmitted -#define ISR_PR (1 << 0) // Packet Received -#define ISR_CLR_STATUS (ISR_LNKCHGS | ISR_ROO | ISR_ROS | ISR_PT | ISR_PR) - -#define IMR_PAR (1 << 7) // Pointer Auto-Return Mode -#define IMR_LNKCHGI (1 << 5) // Enable Link Status Change Interrupt -#define IMR_ROOI (1 << 3) // Enable Receive Overflow Counter Overflow Interrupt -#define IMR_ROI (1 << 2) // Enable Receive Overflow Interrupt -#define IMR_PTI (1 << 1) // Enable Packet Transmitted Interrupt -#define IMR_PRI (1 << 0) // Enable Packet Received Interrupt -#define IMR_ALL (IMR_PAR | IMR_LNKCHGI | IMR_ROOI | IMR_ROI | IMR_PTI | IMR_PRI) - typedef struct { uint8_t flag; uint8_t status; @@ -194,6 +57,7 @@ typedef struct { SemaphoreHandle_t spi_lock; TaskHandle_t rx_task_hdl; uint32_t sw_reset_timeout_ms; + int int_gpio_num; uint8_t addr[6]; bool packets_remain; } emac_dm9051_t; @@ -506,7 +370,7 @@ err: return ret; } -static void dm9051_isr_handler(void *arg) +IRAM_ATTR static void dm9051_isr_handler(void *arg) { emac_dm9051_t *emac = (emac_dm9051_t *)arg; BaseType_t high_task_wakeup = pdFALSE; @@ -806,13 +670,12 @@ static esp_err_t emac_dm9051_init(esp_eth_mac_t *mac) esp_err_t ret = ESP_OK; emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); esp_eth_mediator_t *eth = emac->eth; - /* init gpio used by spi-ethernet interrupt */ - gpio_pad_select_gpio(CONFIG_ETH_DM9051_INT_GPIO); - gpio_set_direction(CONFIG_ETH_DM9051_INT_GPIO, GPIO_MODE_INPUT); - gpio_set_pull_mode(CONFIG_ETH_DM9051_INT_GPIO, GPIO_PULLDOWN_ONLY); - gpio_set_intr_type(CONFIG_ETH_DM9051_INT_GPIO, GPIO_INTR_POSEDGE); - gpio_intr_enable(CONFIG_ETH_DM9051_INT_GPIO); - gpio_isr_handler_add(CONFIG_ETH_DM9051_INT_GPIO, dm9051_isr_handler, emac); + gpio_pad_select_gpio(emac->int_gpio_num); + gpio_set_direction(emac->int_gpio_num, GPIO_MODE_INPUT); + gpio_set_pull_mode(emac->int_gpio_num, GPIO_PULLDOWN_ONLY); + gpio_set_intr_type(emac->int_gpio_num, GPIO_INTR_POSEDGE); + gpio_intr_enable(emac->int_gpio_num); + gpio_isr_handler_add(emac->int_gpio_num, dm9051_isr_handler, emac); MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, "lowlevel init failed", err, ESP_FAIL); /* reset dm9051 */ MAC_CHECK(dm9051_reset(emac) == ESP_OK, "reset dm9051 failed", err, ESP_FAIL); @@ -826,8 +689,8 @@ static esp_err_t emac_dm9051_init(esp_eth_mac_t *mac) MAC_CHECK(dm9051_get_mac_addr(emac) == ESP_OK, "fetch ethernet mac address failed", err, ESP_FAIL); return ESP_OK; err: - gpio_isr_handler_remove(CONFIG_ETH_DM9051_INT_GPIO); - gpio_reset_pin(CONFIG_ETH_DM9051_INT_GPIO); + gpio_isr_handler_remove(emac->int_gpio_num); + gpio_reset_pin(emac->int_gpio_num); eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL); return ret; } @@ -837,8 +700,8 @@ static esp_err_t emac_dm9051_deinit(esp_eth_mac_t *mac) emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); esp_eth_mediator_t *eth = emac->eth; dm9051_stop(emac); - gpio_isr_handler_remove(CONFIG_ETH_DM9051_INT_GPIO); - gpio_reset_pin(CONFIG_ETH_DM9051_INT_GPIO); + gpio_isr_handler_remove(emac->int_gpio_num); + gpio_reset_pin(emac->int_gpio_num); eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL); return ESP_OK; } @@ -862,8 +725,11 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config, MAC_CHECK(mac_config, "can't set mac config to null", err, NULL); emac = calloc(1, sizeof(emac_dm9051_t)); MAC_CHECK(emac, "calloc emac failed", err, NULL); + /* dm9051 receive is driven by interrupt only for now*/ + MAC_CHECK(dm9051_config->int_gpio_num >= 0, "error interrupt gpio number", err, NULL); /* bind methods and attributes */ emac->sw_reset_timeout_ms = mac_config->sw_reset_timeout_ms; + emac->int_gpio_num = dm9051_config->int_gpio_num; emac->spi_hdl = dm9051_config->spi_hdl; emac->parent.set_mediator = emac_dm9051_set_mediator; emac->parent.init = emac_dm9051_init; diff --git a/components/esp_eth/src/esp_eth_mac_esp32.c b/components/esp_eth/src/esp_eth_mac_esp32.c index d8cbc15004..61d28a030a 100644 --- a/components/esp_eth/src/esp_eth_mac_esp32.c +++ b/components/esp_eth/src/esp_eth_mac_esp32.c @@ -16,6 +16,7 @@ #include #include "driver/periph_ctrl.h" #include "driver/gpio.h" +#include "esp_attr.h" #include "esp_log.h" #include "esp_eth.h" #include "esp_system.h" @@ -50,6 +51,8 @@ typedef struct { TaskHandle_t rx_task_hdl; uint32_t sw_reset_timeout_ms; uint32_t frames_remain; + int smi_mdc_gpio_num; + int smi_mdio_gpio_num; uint8_t addr[6]; uint8_t *rx_buf[CONFIG_ETH_DMA_RX_BUFFER_NUM]; uint8_t *tx_buf[CONFIG_ETH_DMA_TX_BUFFER_NUM]; @@ -264,17 +267,17 @@ static void emac_esp32_rx_task(void *arg) vTaskDelete(NULL); } -static void emac_esp32_init_smi_gpio(void) +static void emac_esp32_init_smi_gpio(emac_esp32_t *emac) { /* Setup SMI MDC GPIO */ - gpio_set_direction(CONFIG_ETH_SMI_MDC_GPIO, GPIO_MODE_OUTPUT); - gpio_matrix_out(CONFIG_ETH_SMI_MDC_GPIO, EMAC_MDC_O_IDX, false, false); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CONFIG_ETH_SMI_MDC_GPIO], PIN_FUNC_GPIO); + gpio_set_direction(emac->smi_mdc_gpio_num, GPIO_MODE_OUTPUT); + gpio_matrix_out(emac->smi_mdc_gpio_num, EMAC_MDC_O_IDX, false, false); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[emac->smi_mdc_gpio_num], PIN_FUNC_GPIO); /* Setup SMI MDIO GPIO */ - gpio_set_direction(CONFIG_ETH_SMI_MDIO_GPIO, GPIO_MODE_INPUT_OUTPUT); - gpio_matrix_out(CONFIG_ETH_SMI_MDIO_GPIO, EMAC_MDO_O_IDX, false, false); - gpio_matrix_in(CONFIG_ETH_SMI_MDIO_GPIO, EMAC_MDI_I_IDX, false); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CONFIG_ETH_SMI_MDIO_GPIO], PIN_FUNC_GPIO); + gpio_set_direction(emac->smi_mdio_gpio_num, GPIO_MODE_INPUT_OUTPUT); + gpio_matrix_out(emac->smi_mdio_gpio_num, EMAC_MDO_O_IDX, false, false); + gpio_matrix_in(emac->smi_mdio_gpio_num, EMAC_MDI_I_IDX, false); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[emac->smi_mdio_gpio_num], PIN_FUNC_GPIO); } static esp_err_t emac_esp32_init(esp_eth_mac_t *mac) @@ -287,12 +290,7 @@ static esp_err_t emac_esp32_init(esp_eth_mac_t *mac) /* enable clock, config gpio, etc */ emac_hal_lowlevel_init(&emac->hal); /* init gpio used by gpio */ - emac_esp32_init_smi_gpio(); -#if CONFIG_ETH_PHY_USE_RST - gpio_pad_select_gpio(CONFIG_ETH_PHY_RST_GPIO); - gpio_set_direction(CONFIG_ETH_PHY_RST_GPIO, GPIO_MODE_OUTPUT); - gpio_set_level(CONFIG_ETH_PHY_RST_GPIO, 1); -#endif + emac_esp32_init_smi_gpio(emac); MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, "lowlevel init failed", err, ESP_FAIL); /* software reset */ emac_hal_reset(&emac->hal); @@ -327,9 +325,6 @@ static esp_err_t emac_esp32_deinit(esp_eth_mac_t *mac) { emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); esp_eth_mediator_t *eth = emac->eth; -#if CONFIG_ETH_PHY_USE_RST - gpio_set_level(CONFIG_ETH_PHY_RST_GPIO, 0); -#endif emac_hal_stop(&emac->hal); eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL); periph_module_disable(PERIPH_EMAC_MODULE); @@ -355,7 +350,7 @@ static esp_err_t emac_esp32_del(esp_eth_mac_t *mac) return ESP_OK; } -void emac_esp32_isr_handler(void *args) +IRAM_ATTR void emac_esp32_isr_handler(void *args) { emac_hal_context_t *hal = (emac_hal_context_t *)args; emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal); @@ -396,6 +391,8 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config) /* initialize hal layer driver */ emac_hal_init(&emac->hal, descriptors, emac->rx_buf, emac->tx_buf); emac->sw_reset_timeout_ms = config->sw_reset_timeout_ms; + emac->smi_mdc_gpio_num = config->smi_mdc_gpio_num; + emac->smi_mdio_gpio_num = config->smi_mdio_gpio_num; emac->parent.set_mediator = emac_esp32_set_mediator; emac->parent.init = emac_esp32_init; emac->parent.deinit = emac_esp32_deinit; @@ -443,7 +440,7 @@ err: return ret; } -void emac_hal_rx_complete_cb(void *arg) +IRAM_ATTR void emac_hal_rx_complete_cb(void *arg) { emac_hal_context_t *hal = (emac_hal_context_t *)arg; emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal); @@ -455,7 +452,7 @@ void emac_hal_rx_complete_cb(void *arg) } } -void emac_hal_rx_unavail_cb(void *arg) +IRAM_ATTR void emac_hal_rx_unavail_cb(void *arg) { emac_hal_context_t *hal = (emac_hal_context_t *)arg; emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal); diff --git a/components/esp_eth/src/esp_eth_phy_dm9051.c b/components/esp_eth/src/esp_eth_phy_dm9051.c index a04a5568bd..19db41267e 100644 --- a/components/esp_eth/src/esp_eth_phy_dm9051.c +++ b/components/esp_eth/src/esp_eth_phy_dm9051.c @@ -19,6 +19,7 @@ #include "eth_phy_regs_struct.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "driver/gpio.h" static const char *TAG = "dm9051"; #define PHY_CHECK(a, str, goto_tag, ...) \ @@ -83,6 +84,7 @@ typedef struct { uint32_t reset_timeout_ms; uint32_t autonego_timeout_ms; eth_link_t link_status; + int reset_gpio_num; } phy_dm9051_t; static esp_err_t dm9051_update_link_duplex_speed(phy_dm9051_t *dm9051) @@ -176,6 +178,19 @@ err: return ESP_FAIL; } +static esp_err_t dm9051_reset_hw(esp_eth_phy_t *phy) +{ + phy_dm9051_t *dm9051 = __containerof(phy, phy_dm9051_t, parent); + // set reset_gpio_num minus zero can skip hardware reset phy chip + if (dm9051->reset_gpio_num >= 0) { + gpio_pad_select_gpio(dm9051->reset_gpio_num); + gpio_set_direction(dm9051->reset_gpio_num, GPIO_MODE_OUTPUT); + gpio_set_level(dm9051->reset_gpio_num, 0); + gpio_set_level(dm9051->reset_gpio_num, 1); + } + return ESP_OK; +} + static esp_err_t dm9051_negotiate(esp_eth_phy_t *phy) { phy_dm9051_t *dm9051 = __containerof(phy, phy_dm9051_t, parent); @@ -306,9 +321,11 @@ esp_eth_phy_t *esp_eth_phy_new_dm9051(const eth_phy_config_t *config) PHY_CHECK(dm9051, "calloc dm9051 failed", err); dm9051->addr = config->phy_addr; dm9051->reset_timeout_ms = config->reset_timeout_ms; + dm9051->reset_gpio_num = config->reset_gpio_num; dm9051->link_status = ETH_LINK_DOWN; dm9051->autonego_timeout_ms = config->autonego_timeout_ms; dm9051->parent.reset = dm9051_reset; + dm9051->parent.reset_hw = dm9051_reset_hw; dm9051->parent.init = dm9051_init; dm9051->parent.deinit = dm9051_deinit; dm9051->parent.set_mediator = dm9051_set_mediator; diff --git a/components/esp_eth/src/esp_eth_phy_dp83848.c b/components/esp_eth/src/esp_eth_phy_dp83848.c index 5f98fc0442..bb82cb8c30 100644 --- a/components/esp_eth/src/esp_eth_phy_dp83848.c +++ b/components/esp_eth/src/esp_eth_phy_dp83848.c @@ -19,6 +19,7 @@ #include "eth_phy_regs_struct.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "driver/gpio.h" static const char *TAG = "dp83848"; #define PHY_CHECK(a, str, goto_tag, ...) \ @@ -89,6 +90,7 @@ typedef struct { uint32_t reset_timeout_ms; uint32_t autonego_timeout_ms; eth_link_t link_status; + int reset_gpio_num; } phy_dp83848_t; static esp_err_t dp83848_update_link_duplex_speed(phy_dp83848_t *dp83848) @@ -174,6 +176,18 @@ err: return ESP_FAIL; } +static esp_err_t dp83848_reset_hw(esp_eth_phy_t *phy) +{ + phy_dp83848_t *dp83848 = __containerof(phy, phy_dp83848_t, parent); + if (dp83848->reset_gpio_num >= 0) { + gpio_pad_select_gpio(dp83848->reset_gpio_num); + gpio_set_direction(dp83848->reset_gpio_num, GPIO_MODE_OUTPUT); + gpio_set_level(dp83848->reset_gpio_num, 0); + gpio_set_level(dp83848->reset_gpio_num, 1); + } + return ESP_OK; +} + static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy) { phy_dp83848_t *dp83848 = __containerof(phy, phy_dp83848_t, parent); @@ -305,8 +319,10 @@ esp_eth_phy_t *esp_eth_phy_new_dp83848(const eth_phy_config_t *config) dp83848->addr = config->phy_addr; dp83848->reset_timeout_ms = config->reset_timeout_ms; dp83848->link_status = ETH_LINK_DOWN; + dp83848->reset_gpio_num = config->reset_gpio_num; dp83848->autonego_timeout_ms = config->autonego_timeout_ms; dp83848->parent.reset = dp83848_reset; + dp83848->parent.reset_hw = dp83848_reset_hw; dp83848->parent.init = dp83848_init; dp83848->parent.deinit = dp83848_deinit; dp83848->parent.set_mediator = dp83848_set_mediator; diff --git a/components/esp_eth/src/esp_eth_phy_ip101.c b/components/esp_eth/src/esp_eth_phy_ip101.c index 9c6dc5d06b..5bb92ec0a3 100644 --- a/components/esp_eth/src/esp_eth_phy_ip101.c +++ b/components/esp_eth/src/esp_eth_phy_ip101.c @@ -19,6 +19,7 @@ #include "eth_phy_regs_struct.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "driver/gpio.h" static const char *TAG = "ip101"; #define PHY_CHECK(a, str, goto_tag, ...) \ @@ -106,6 +107,7 @@ typedef struct { uint32_t reset_timeout_ms; uint32_t autonego_timeout_ms; eth_link_t link_status; + int reset_gpio_num; } phy_ip101_t; static esp_err_t ip101_page_select(phy_ip101_t *ip101, uint32_t page) @@ -214,6 +216,18 @@ err: return ESP_FAIL; } +static esp_err_t ip101_reset_hw(esp_eth_phy_t *phy) +{ + phy_ip101_t *ip101 = __containerof(phy, phy_ip101_t, parent); + if (ip101->reset_gpio_num >= 0) { + gpio_pad_select_gpio(ip101->reset_gpio_num); + gpio_set_direction(ip101->reset_gpio_num, GPIO_MODE_OUTPUT); + gpio_set_level(ip101->reset_gpio_num, 0); + gpio_set_level(ip101->reset_gpio_num, 1); + } + return ESP_OK; +} + static esp_err_t ip101_negotiate(esp_eth_phy_t *phy) { phy_ip101_t *ip101 = __containerof(phy, phy_ip101_t, parent); @@ -338,9 +352,11 @@ esp_eth_phy_t *esp_eth_phy_new_ip101(const eth_phy_config_t *config) PHY_CHECK(ip101, "calloc ip101 failed", err); ip101->addr = config->phy_addr; ip101->reset_timeout_ms = config->reset_timeout_ms; + ip101->reset_gpio_num = config->reset_gpio_num; ip101->link_status = ETH_LINK_DOWN; ip101->autonego_timeout_ms = config->autonego_timeout_ms; ip101->parent.reset = ip101_reset; + ip101->parent.reset_hw = ip101_reset_hw; ip101->parent.init = ip101_init; ip101->parent.deinit = ip101_deinit; ip101->parent.set_mediator = ip101_set_mediator; diff --git a/components/esp_eth/src/esp_eth_phy_lan8720.c b/components/esp_eth/src/esp_eth_phy_lan8720.c index 1afbcdbfb3..8289faf59d 100644 --- a/components/esp_eth/src/esp_eth_phy_lan8720.c +++ b/components/esp_eth/src/esp_eth_phy_lan8720.c @@ -19,6 +19,7 @@ #include "eth_phy_regs_struct.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "driver/gpio.h" static const char *TAG = "lan8720"; #define PHY_CHECK(a, str, goto_tag, ...) \ @@ -161,6 +162,7 @@ typedef struct { uint32_t reset_timeout_ms; uint32_t autonego_timeout_ms; eth_link_t link_status; + int reset_gpio_num; } phy_lan8720_t; static esp_err_t lan8720_update_link_duplex_speed(phy_lan8720_t *lan8720) @@ -256,6 +258,18 @@ err: return ESP_FAIL; } +static esp_err_t lan8720_reset_hw(esp_eth_phy_t *phy) +{ + phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent); + if (lan8720->reset_gpio_num >= 0) { + gpio_pad_select_gpio(lan8720->reset_gpio_num); + gpio_set_direction(lan8720->reset_gpio_num, GPIO_MODE_OUTPUT); + gpio_set_level(lan8720->reset_gpio_num, 0); + gpio_set_level(lan8720->reset_gpio_num, 1); + } + return ESP_OK; +} + static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy) { phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent); @@ -383,10 +397,12 @@ esp_eth_phy_t *esp_eth_phy_new_lan8720(const eth_phy_config_t *config) phy_lan8720_t *lan8720 = calloc(1, sizeof(phy_lan8720_t)); PHY_CHECK(lan8720, "calloc lan8720 failed", err); lan8720->addr = config->phy_addr; + lan8720->reset_gpio_num = config->reset_gpio_num; lan8720->reset_timeout_ms = config->reset_timeout_ms; lan8720->link_status = ETH_LINK_DOWN; lan8720->autonego_timeout_ms = config->autonego_timeout_ms; lan8720->parent.reset = lan8720_reset; + lan8720->parent.reset_hw = lan8720_reset_hw; lan8720->parent.init = lan8720_init; lan8720->parent.deinit = lan8720_deinit; lan8720->parent.set_mediator = lan8720_set_mediator; diff --git a/components/esp_eth/src/esp_eth_phy_rtl8201.c b/components/esp_eth/src/esp_eth_phy_rtl8201.c index 95152acb72..be3c3038a2 100644 --- a/components/esp_eth/src/esp_eth_phy_rtl8201.c +++ b/components/esp_eth/src/esp_eth_phy_rtl8201.c @@ -20,6 +20,7 @@ #include "eth_phy_regs_struct.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "driver/gpio.h" static const char *TAG = "rtl8201"; #define PHY_CHECK(a, str, goto_tag, ...) \ @@ -67,6 +68,7 @@ typedef struct { uint32_t reset_timeout_ms; uint32_t autonego_timeout_ms; eth_link_t link_status; + int reset_gpio_num; } phy_rtl8201_t; static esp_err_t rtl8201_page_select(phy_rtl8201_t *rtl8201, uint32_t page) @@ -165,6 +167,18 @@ err: return ESP_FAIL; } +static esp_err_t rtl8201_reset_hw(esp_eth_phy_t *phy) +{ + phy_rtl8201_t *rtl8201 = __containerof(phy, phy_rtl8201_t, parent); + if (rtl8201->reset_gpio_num >= 0) { + gpio_pad_select_gpio(rtl8201->reset_gpio_num); + gpio_set_direction(rtl8201->reset_gpio_num, GPIO_MODE_OUTPUT); + gpio_set_level(rtl8201->reset_gpio_num, 0); + gpio_set_level(rtl8201->reset_gpio_num, 1); + } + return ESP_OK; +} + static esp_err_t rtl8201_negotiate(esp_eth_phy_t *phy) { phy_rtl8201_t *rtl8201 = __containerof(phy, phy_rtl8201_t, parent); @@ -291,10 +305,12 @@ esp_eth_phy_t *esp_eth_phy_new_rtl8201(const eth_phy_config_t *config) phy_rtl8201_t *rtl8201 = calloc(1, sizeof(phy_rtl8201_t)); PHY_CHECK(rtl8201, "calloc rtl8201 failed", err); rtl8201->addr = config->phy_addr; + rtl8201->reset_gpio_num = config->reset_gpio_num; rtl8201->reset_timeout_ms = config->reset_timeout_ms; rtl8201->link_status = ETH_LINK_DOWN; rtl8201->autonego_timeout_ms = config->autonego_timeout_ms; rtl8201->parent.reset = rtl8201_reset; + rtl8201->parent.reset_hw = rtl8201_reset_hw; rtl8201->parent.init = rtl8201_init; rtl8201->parent.deinit = rtl8201_deinit; rtl8201->parent.set_mediator = rtl8201_set_mediator; diff --git a/components/esp_eth/test/CMakeLists.txt b/components/esp_eth/test/CMakeLists.txt index 789ab04cd1..ea533991a3 100644 --- a/components/esp_eth/test/CMakeLists.txt +++ b/components/esp_eth/test/CMakeLists.txt @@ -1,5 +1,7 @@ -if(IDF_TARGET STREQUAL "esp32") +idf_build_get_property(target IDF_TARGET) +# Currently we only have unit test for esp32 +if(${target} STREQUAL "esp32") idf_component_register(SRC_DIRS . - INCLUDE_DIRS . - PRIV_REQUIRES unity test_utils esp_eth) + INCLUDE_DIRS . + PRIV_REQUIRES unity test_utils esp_eth) endif() diff --git a/components/esp_eth/test/test_emac.c b/components/esp_eth/test/test_emac.c index 51378c6da9..644dbcdd48 100644 --- a/components/esp_eth/test/test_emac.c +++ b/components/esp_eth/test/test_emac.c @@ -9,6 +9,7 @@ #include "esp_event.h" #include "esp_eth.h" #include "esp_log.h" +#include "driver/gpio.h" #include "lwip/inet.h" #include "lwip/netdb.h" #include "lwip/sockets.h" diff --git a/components/soc/esp32/emac_hal.c b/components/soc/esp32/emac_hal.c index 4e39e17bdd..9b0c52e24a 100644 --- a/components/soc/esp32/emac_hal.c +++ b/components/soc/esp32/emac_hal.c @@ -550,7 +550,7 @@ uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t return len; } -void emac_hal_isr(void *arg) +IRAM_ATTR void emac_hal_isr(void *arg) { emac_hal_context_t *hal = (emac_hal_context_t *)arg; typeof(hal->dma_regs->dmastatus) dma_status = hal->dma_regs->dmastatus; @@ -621,7 +621,7 @@ void emac_hal_isr(void *arg) } } -__attribute__((weak)) void emac_hal_tx_complete_cb(void *arg) +IRAM_ATTR __attribute__((weak)) void emac_hal_tx_complete_cb(void *arg) { // This is a weak function, do nothing by default // Upper code can rewrite this function @@ -629,7 +629,7 @@ __attribute__((weak)) void emac_hal_tx_complete_cb(void *arg) return; } -__attribute__((weak)) void emac_hal_tx_unavail_cb(void *arg) +IRAM_ATTR __attribute__((weak)) void emac_hal_tx_unavail_cb(void *arg) { // This is a weak function, do nothing by default // Upper code can rewrite this function @@ -637,7 +637,7 @@ __attribute__((weak)) void emac_hal_tx_unavail_cb(void *arg) return; } -__attribute__((weak)) void emac_hal_rx_complete_cb(void *arg) +IRAM_ATTR __attribute__((weak)) void emac_hal_rx_complete_cb(void *arg) { // This is a weak function, do nothing by default // Upper code can rewrite this function @@ -645,7 +645,7 @@ __attribute__((weak)) void emac_hal_rx_complete_cb(void *arg) return; } -__attribute__((weak)) void emac_hal_rx_early_cb(void *arg) +IRAM_ATTR __attribute__((weak)) void emac_hal_rx_early_cb(void *arg) { // This is a weak function, do nothing by default // Upper code can rewrite this function @@ -653,7 +653,7 @@ __attribute__((weak)) void emac_hal_rx_early_cb(void *arg) return; } -__attribute__((weak)) void emac_hal_rx_unavail_cb(void *arg) +IRAM_ATTR __attribute__((weak)) void emac_hal_rx_unavail_cb(void *arg) { // This is a weak function, do nothing by default // Upper code can rewrite this function diff --git a/components/soc/linker.lf b/components/soc/linker.lf index 21aa0a0331..092322a0c7 100644 --- a/components/soc/linker.lf +++ b/components/soc/linker.lf @@ -14,10 +14,3 @@ entries: spi_slave_hal_iram (noflash_text) spi_flash_hal_iram (noflash) lldesc (noflash_text) - if ETH_USE_ESP32_EMAC = y: - emac_hal:emac_hal_isr (noflash_text) - emac_hal:emac_hal_tx_complete_cb (noflash_text) - emac_hal:emac_hal_tx_unavail_cb (noflash_text) - emac_hal:emac_hal_rx_complete_cb (noflash_text) - emac_hal:emac_hal_rx_early_cb (noflash_text) - emac_hal:emac_hal_rx_unavail_cb (noflash_text) diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index 0e69979836..f8ceb1e405 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -33,7 +33,7 @@ menu "Example Connection Configuration" choice EXAMPLE_USE_ETHERNET prompt "Ethernet Type" default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32 - default EXAMPLE_USE_SPI_ETHERNET if !IDF_TARGET_ESP32 + default EXAMPLE_USE_DM9051 if !IDF_TARGET_ESP32 help Select which kind of Ethernet will be used in the example. @@ -44,9 +44,10 @@ menu "Example Connection Configuration" help Select internal Ethernet MAC controller. - config EXAMPLE_USE_SPI_ETHERNET - bool "SPI Ethernet Module" + config EXAMPLE_USE_DM9051 + bool "DM9051 Module" select ETH_USE_SPI_ETHERNET + select ETH_SPI_ETHERNET_DM9051 help Select external SPI-Ethernet module. @@ -93,51 +94,84 @@ menu "Example Connection Configuration" DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver. Goto http://www.ti.com/product/DP83848J for more information about it. endchoice + + config EXAMPLE_ETH_MDC_GPIO + int "SMI MDC GPIO number" + default 23 + help + Set the GPIO number used by SMI MDC. + + config EXAMPLE_ETH_MDIO_GPIO + int "SMI MDIO GPIO number" + default 18 + help + Set the GPIO number used by SMI MDIO. endif - if EXAMPLE_USE_SPI_ETHERNET - config EXAMPLE_ETH_SPI_HOST + if EXAMPLE_USE_DM9051 + config EXAMPLE_DM9051_SPI_HOST int "SPI Host Number" range 0 2 default 1 help Set the SPI host used to communicate with DM9051. - config EXAMPLE_ETH_SCLK_GPIO + config EXAMPLE_DM9051_SCLK_GPIO int "SPI SCLK GPIO number" range 0 33 default 19 help Set the GPIO number used by SPI SCLK. - config EXAMPLE_ETH_MOSI_GPIO + config EXAMPLE_DM9051_MOSI_GPIO int "SPI MOSI GPIO number" range 0 33 default 23 help Set the GPIO number used by SPI MOSI. - config EXAMPLE_ETH_MISO_GPIO + config EXAMPLE_DM9051_MISO_GPIO int "SPI MISO GPIO number" range 0 33 default 25 help Set the GPIO number used by SPI MISO. - config EXAMPLE_ETH_CS_GPIO + config EXAMPLE_DM9051_CS_GPIO int "SPI CS GPIO number" range 0 33 default 22 help Set the GPIO number used by SPI CS. - config EXAMPLE_ETH_SPI_CLOCK_MHZ + config EXAMPLE_DM9051_SPI_CLOCK_MHZ int "SPI clock speed (MHz)" range 20 80 default 20 help Set the clock speed (MHz) of SPI interface. + + config EXAMPLE_DM9051_INT_GPIO + int "Interrupt GPIO number" + default 4 + help + Set the GPIO number used by DM9051 interrupt. endif + + config EXAMPLE_ETH_PHY_RST_GPIO + int "PHY Reset GPIO number" + default 5 + help + Set the GPIO number used to reset PHY chip. + Set to -1 to disable PHY chip hardware reset. + + config EXAMPLE_ETH_PHY_ADDR + int "PHY Address" + range 0 31 if EXAMPLE_USE_INTERNAL_ETHERNET + range 1 1 if !EXAMPLE_USE_INTERNAL_ETHERNET + default 1 + help + Set PHY address according your board schematic. endif config EXAMPLE_CONNECT_IPV6 diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index b161e9a6ec..f71b323b21 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -18,6 +18,7 @@ #endif #include "esp_log.h" #include "esp_netif.h" +#include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" @@ -227,7 +228,11 @@ static void start(void) #endif eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); + phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; + phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; #if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET + mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; + mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; s_mac = esp_eth_mac_new_esp32(&mac_config); #if CONFIG_EXAMPLE_ETH_PHY_IP101 s_phy = esp_eth_phy_new_ip101(&phy_config); @@ -238,28 +243,29 @@ static void start(void) #elif CONFIG_EXAMPLE_ETH_PHY_DP83848 s_phy = esp_eth_phy_new_dp83848(&phy_config); #endif -#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET +#elif CONFIG_EXAMPLE_USE_DM9051 gpio_install_isr_service(0); spi_device_handle_t spi_handle = NULL; spi_bus_config_t buscfg = { - .miso_io_num = CONFIG_EXAMPLE_ETH_MISO_GPIO, - .mosi_io_num = CONFIG_EXAMPLE_ETH_MOSI_GPIO, - .sclk_io_num = CONFIG_EXAMPLE_ETH_SCLK_GPIO, + .miso_io_num = CONFIG_EXAMPLE_DM9051_MISO_GPIO, + .mosi_io_num = CONFIG_EXAMPLE_DM9051_MOSI_GPIO, + .sclk_io_num = CONFIG_EXAMPLE_DM9051_SCLK_GPIO, .quadwp_io_num = -1, .quadhd_io_num = -1, }; - ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1)); + ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_DM9051_SPI_HOST, &buscfg, 1)); spi_device_interface_config_t devcfg = { .command_bits = 1, .address_bits = 7, .mode = 0, - .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, - .spics_io_num = CONFIG_EXAMPLE_ETH_CS_GPIO, + .clock_speed_hz = CONFIG_EXAMPLE_DM9051_SPI_CLOCK_MHZ * 1000 * 1000, + .spics_io_num = CONFIG_EXAMPLE_DM9051_CS_GPIO, .queue_size = 20 }; - ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle)); + ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_DM9051_SPI_HOST, &devcfg, &spi_handle)); /* dm9051 ethernet driver is based on spi driver */ eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle); + dm9051_config.int_gpio_num = CONFIG_EXAMPLE_DM9051_INT_GPIO; s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config); s_phy = esp_eth_phy_new_dm9051(&phy_config); #elif CONFIG_EXAMPLE_USE_OPENETH @@ -297,4 +303,4 @@ static void stop(void) esp_netif_t *get_example_netif(void) { return s_example_esp_netif; -} \ No newline at end of file +} diff --git a/examples/ethernet/basic/main/Kconfig.projbuild b/examples/ethernet/basic/main/Kconfig.projbuild index 9c6cae1f73..167a1ede20 100644 --- a/examples/ethernet/basic/main/Kconfig.projbuild +++ b/examples/ethernet/basic/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" choice EXAMPLE_USE_ETHERNET prompt "Ethernet Type" default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32 - default EXAMPLE_USE_SPI_ETHERNET if !IDF_TARGET_ESP32 + default EXAMPLE_USE_DM9051 if !IDF_TARGET_ESP32 help Select which kind of Ethernet will be used in the example. @@ -13,9 +13,10 @@ menu "Example Configuration" help Select internal Ethernet MAC controller. - config EXAMPLE_USE_SPI_ETHERNET - bool "SPI Ethernet Module" + config EXAMPLE_USE_DM9051 + bool "DM9051 Module" select ETH_USE_SPI_ETHERNET + select ETH_SPI_ETHERNET_DM9051 help Select external SPI-Ethernet module. endchoice @@ -51,49 +52,82 @@ menu "Example Configuration" DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver. Goto http://www.ti.com/product/DP83848J for more information about it. endchoice + + config EXAMPLE_ETH_MDC_GPIO + int "SMI MDC GPIO number" + default 23 + help + Set the GPIO number used by SMI MDC. + + config EXAMPLE_ETH_MDIO_GPIO + int "SMI MDIO GPIO number" + default 18 + help + Set the GPIO number used by SMI MDIO. endif - if EXAMPLE_USE_SPI_ETHERNET - config EXAMPLE_ETH_SPI_HOST + if EXAMPLE_USE_DM9051 + config EXAMPLE_DM9051_SPI_HOST int "SPI Host Number" range 0 2 default 1 help Set the SPI host used to communicate with DM9051. - config EXAMPLE_ETH_SCLK_GPIO + config EXAMPLE_DM9051_SCLK_GPIO int "SPI SCLK GPIO number" range 0 33 default 19 help Set the GPIO number used by SPI SCLK. - config EXAMPLE_ETH_MOSI_GPIO + config EXAMPLE_DM9051_MOSI_GPIO int "SPI MOSI GPIO number" range 0 33 default 23 help Set the GPIO number used by SPI MOSI. - config EXAMPLE_ETH_MISO_GPIO + config EXAMPLE_DM9051_MISO_GPIO int "SPI MISO GPIO number" range 0 33 default 25 help Set the GPIO number used by SPI MISO. - config EXAMPLE_ETH_CS_GPIO + config EXAMPLE_DM9051_CS_GPIO int "SPI CS GPIO number" range 0 33 default 22 help Set the GPIO number used by SPI CS. - config EXAMPLE_ETH_SPI_CLOCK_MHZ + config EXAMPLE_DM9051_SPI_CLOCK_MHZ int "SPI clock speed (MHz)" range 20 80 default 20 help Set the clock speed (MHz) of SPI interface. + + config EXAMPLE_DM9051_INT_GPIO + int "Interrupt GPIO number" + default 4 + help + Set the GPIO number used by DM9051 interrupt. endif + + config EXAMPLE_ETH_PHY_RST_GPIO + int "PHY Reset GPIO number" + default 5 + help + Set the GPIO number used to reset PHY chip. + Set to -1 to disable PHY chip hardware reset. + + config EXAMPLE_ETH_PHY_ADDR + int "PHY Address" + range 0 31 if EXAMPLE_USE_INTERNAL_ETHERNET + range 1 1 if !EXAMPLE_USE_INTERNAL_ETHERNET + default 1 + help + Set PHY address according your board schematic. endmenu diff --git a/examples/ethernet/basic/main/ethernet_example_main.c b/examples/ethernet/basic/main/ethernet_example_main.c index 136d5f6879..f7df43ed70 100644 --- a/examples/ethernet/basic/main/ethernet_example_main.c +++ b/examples/ethernet/basic/main/ethernet_example_main.c @@ -14,6 +14,7 @@ #include "esp_eth.h" #include "esp_event.h" #include "esp_log.h" +#include "driver/gpio.h" #include "sdkconfig.h" static const char *TAG = "eth_example"; @@ -75,7 +76,11 @@ void app_main(void) eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); + phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; + phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; #if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET + mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; + mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config); #if CONFIG_EXAMPLE_ETH_PHY_IP101 esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); @@ -86,28 +91,29 @@ void app_main(void) #elif CONFIG_EXAMPLE_ETH_PHY_DP83848 esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config); #endif -#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET +#elif CONFIG_EXAMPLE_USE_DM9051 gpio_install_isr_service(0); spi_device_handle_t spi_handle = NULL; spi_bus_config_t buscfg = { - .miso_io_num = CONFIG_EXAMPLE_ETH_MISO_GPIO, - .mosi_io_num = CONFIG_EXAMPLE_ETH_MOSI_GPIO, - .sclk_io_num = CONFIG_EXAMPLE_ETH_SCLK_GPIO, + .miso_io_num = CONFIG_EXAMPLE_DM9051_MISO_GPIO, + .mosi_io_num = CONFIG_EXAMPLE_DM9051_MOSI_GPIO, + .sclk_io_num = CONFIG_EXAMPLE_DM9051_SCLK_GPIO, .quadwp_io_num = -1, .quadhd_io_num = -1, }; - ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1)); + ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_DM9051_SPI_HOST, &buscfg, 1)); spi_device_interface_config_t devcfg = { .command_bits = 1, .address_bits = 7, .mode = 0, - .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, - .spics_io_num = CONFIG_EXAMPLE_ETH_CS_GPIO, + .clock_speed_hz = CONFIG_EXAMPLE_DM9051_SPI_CLOCK_MHZ * 1000 * 1000, + .spics_io_num = CONFIG_EXAMPLE_DM9051_CS_GPIO, .queue_size = 20 }; - ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle)); + ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_DM9051_SPI_HOST, &devcfg, &spi_handle)); /* dm9051 ethernet driver is based on spi driver */ eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle); + dm9051_config.int_gpio_num = CONFIG_EXAMPLE_DM9051_INT_GPIO; esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config); esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config); #endif diff --git a/examples/ethernet/eth2ap/main/Kconfig.projbuild b/examples/ethernet/eth2ap/main/Kconfig.projbuild index 40b54b9ad3..8497f862d8 100644 --- a/examples/ethernet/eth2ap/main/Kconfig.projbuild +++ b/examples/ethernet/eth2ap/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" choice EXAMPLE_USE_ETHERNET prompt "Ethernet Type" default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32 - default EXAMPLE_USE_SPI_ETHERNET if !IDF_TARGET_ESP32 + default EXAMPLE_USE_DM9051 if !IDF_TARGET_ESP32 help Select which kind of Ethernet will be used in the example. @@ -13,9 +13,10 @@ menu "Example Configuration" help Select internal Ethernet MAC controller. - config EXAMPLE_USE_SPI_ETHERNET - bool "SPI Ethernet Module" + config EXAMPLE_USE_DM9051 + bool "DM9051 Module" select ETH_USE_SPI_ETHERNET + select ETH_SPI_ETHERNET_DM9051 help Select external SPI-Ethernet module. endchoice @@ -51,52 +52,85 @@ menu "Example Configuration" DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver. Goto http://www.ti.com/product/DP83848J for more information about it. endchoice + + config EXAMPLE_ETH_MDC_GPIO + int "SMI MDC GPIO number" + default 23 + help + Set the GPIO number used by SMI MDC. + + config EXAMPLE_ETH_MDIO_GPIO + int "SMI MDIO GPIO number" + default 18 + help + Set the GPIO number used by SMI MDIO. endif - if EXAMPLE_USE_SPI_ETHERNET - config EXAMPLE_ETH_SPI_HOST + if EXAMPLE_USE_DM9051 + config EXAMPLE_DM9051_SPI_HOST int "SPI Host Number" range 0 2 default 1 help Set the SPI host used to communicate with DM9051. - config EXAMPLE_ETH_SCLK_GPIO + config EXAMPLE_DM9051_SCLK_GPIO int "SPI SCLK GPIO number" range 0 33 default 19 help Set the GPIO number used by SPI SCLK. - config EXAMPLE_ETH_MOSI_GPIO + config EXAMPLE_DM9051_MOSI_GPIO int "SPI MOSI GPIO number" range 0 33 default 23 help Set the GPIO number used by SPI MOSI. - config EXAMPLE_ETH_MISO_GPIO + config EXAMPLE_DM9051_MISO_GPIO int "SPI MISO GPIO number" range 0 33 default 25 help Set the GPIO number used by SPI MISO. - config EXAMPLE_ETH_CS_GPIO + config EXAMPLE_DM9051_CS_GPIO int "SPI CS GPIO number" range 0 33 default 22 help Set the GPIO number used by SPI CS. - config EXAMPLE_ETH_SPI_CLOCK_MHZ + config EXAMPLE_DM9051_SPI_CLOCK_MHZ int "SPI clock speed (MHz)" range 20 80 default 20 help Set the clock speed (MHz) of SPI interface. + + config EXAMPLE_DM9051_INT_GPIO + int "Interrupt GPIO number" + default 4 + help + Set the GPIO number used by DM9051 interrupt. endif + config EXAMPLE_ETH_PHY_RST_GPIO + int "PHY Reset GPIO number" + default 5 + help + Set the GPIO number used to reset PHY chip. + Set to -1 to disable PHY chip hardware reset. + + config EXAMPLE_ETH_PHY_ADDR + int "PHY Address" + range 0 31 if EXAMPLE_USE_INTERNAL_ETHERNET + range 1 1 if !EXAMPLE_USE_INTERNAL_ETHERNET + default 1 + help + Set PHY address according your board schematic. + config EXAMPLE_WIFI_SSID string "Wi-Fi SSID" default "eth2ap" diff --git a/examples/ethernet/eth2ap/main/ethernet_example_main.c b/examples/ethernet/eth2ap/main/ethernet_example_main.c index 78c04b1e8b..413c6a4140 100644 --- a/examples/ethernet/eth2ap/main/ethernet_example_main.c +++ b/examples/ethernet/eth2ap/main/ethernet_example_main.c @@ -145,7 +145,11 @@ static void initialize_ethernet(void) ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler, NULL)); eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); + phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; + phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; #if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET + mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; + mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config); #if CONFIG_EXAMPLE_ETH_PHY_IP101 esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); @@ -156,28 +160,29 @@ static void initialize_ethernet(void) #elif CONFIG_EXAMPLE_ETH_PHY_DP83848 esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config); #endif -#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET +#elif CONFIG_EXAMPLE_USE_DM9051 gpio_install_isr_service(0); spi_device_handle_t spi_handle = NULL; spi_bus_config_t buscfg = { - .miso_io_num = CONFIG_EXAMPLE_ETH_MISO_GPIO, - .mosi_io_num = CONFIG_EXAMPLE_ETH_MOSI_GPIO, - .sclk_io_num = CONFIG_EXAMPLE_ETH_SCLK_GPIO, + .miso_io_num = CONFIG_EXAMPLE_DM9051_MISO_GPIO, + .mosi_io_num = CONFIG_EXAMPLE_DM9051_MOSI_GPIO, + .sclk_io_num = CONFIG_EXAMPLE_DM9051_SCLK_GPIO, .quadwp_io_num = -1, .quadhd_io_num = -1, }; - ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1)); + ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_DM9051_SPI_HOST, &buscfg, 1)); spi_device_interface_config_t devcfg = { .command_bits = 1, .address_bits = 7, .mode = 0, - .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, - .spics_io_num = CONFIG_EXAMPLE_ETH_CS_GPIO, + .clock_speed_hz = CONFIG_EXAMPLE_DM9051_SPI_CLOCK_MHZ * 1000 * 1000, + .spics_io_num = CONFIG_EXAMPLE_DM9051_CS_GPIO, .queue_size = 20 }; - ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle)); + ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_DM9051_SPI_HOST, &devcfg, &spi_handle)); /* dm9051 ethernet driver is based on spi driver */ eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle); + dm9051_config.int_gpio_num = CONFIG_EXAMPLE_DM9051_INT_GPIO; esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config); esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config); #endif diff --git a/examples/ethernet/iperf/main/Kconfig.projbuild b/examples/ethernet/iperf/main/Kconfig.projbuild index b84eefa7e7..e71121e188 100644 --- a/examples/ethernet/iperf/main/Kconfig.projbuild +++ b/examples/ethernet/iperf/main/Kconfig.projbuild @@ -10,7 +10,7 @@ menu "Example Configuration" choice EXAMPLE_USE_ETHERNET prompt "Ethernet Type" default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32 - default EXAMPLE_USE_SPI_ETHERNET if !IDF_TARGET_ESP32 + default EXAMPLE_USE_DM9051 if !IDF_TARGET_ESP32 help Select which kind of Ethernet will be used in the example. @@ -21,9 +21,10 @@ menu "Example Configuration" help Select internal Ethernet MAC controller. - config EXAMPLE_USE_SPI_ETHERNET - bool "SPI Ethernet Module" + config EXAMPLE_USE_DM9051 + bool "DM9051 Module" select ETH_USE_SPI_ETHERNET + select ETH_SPI_ETHERNET_DM9051 help Select external SPI-Ethernet module. endchoice @@ -59,49 +60,82 @@ menu "Example Configuration" DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver. Goto http://www.ti.com/product/DP83848J for more information about it. endchoice + + config EXAMPLE_ETH_MDC_GPIO + int "SMI MDC GPIO number" + default 23 + help + Set the GPIO number used by SMI MDC. + + config EXAMPLE_ETH_MDIO_GPIO + int "SMI MDIO GPIO number" + default 18 + help + Set the GPIO number used by SMI MDIO. endif - if EXAMPLE_USE_SPI_ETHERNET - config EXAMPLE_ETH_SPI_HOST + if EXAMPLE_USE_DM9051 + config EXAMPLE_DM9051_SPI_HOST int "SPI Host Number" range 0 2 default 1 help Set the SPI host used to communicate with DM9051. - config EXAMPLE_ETH_SCLK_GPIO + config EXAMPLE_DM9051_SCLK_GPIO int "SPI SCLK GPIO number" range 0 33 default 19 help Set the GPIO number used by SPI SCLK. - config EXAMPLE_ETH_MOSI_GPIO + config EXAMPLE_DM9051_MOSI_GPIO int "SPI MOSI GPIO number" range 0 33 default 23 help Set the GPIO number used by SPI MOSI. - config EXAMPLE_ETH_MISO_GPIO + config EXAMPLE_DM9051_MISO_GPIO int "SPI MISO GPIO number" range 0 33 default 25 help Set the GPIO number used by SPI MISO. - config EXAMPLE_ETH_CS_GPIO + config EXAMPLE_DM9051_CS_GPIO int "SPI CS GPIO number" range 0 33 default 22 help Set the GPIO number used by SPI CS. - config EXAMPLE_ETH_SPI_CLOCK_MHZ + config EXAMPLE_DM9051_SPI_CLOCK_MHZ int "SPI clock speed (MHz)" range 20 80 default 20 help Set the clock speed (MHz) of SPI interface. + + config EXAMPLE_DM9051_INT_GPIO + int "Interrupt GPIO number" + default 4 + help + Set the GPIO number used by DM9051 interrupt. endif + + config EXAMPLE_ETH_PHY_RST_GPIO + int "PHY Reset GPIO number" + default 5 + help + Set the GPIO number used to reset PHY chip. + Set to -1 to disable PHY chip hardware reset. + + config EXAMPLE_ETH_PHY_ADDR + int "PHY Address" + range 0 31 if EXAMPLE_USE_INTERNAL_ETHERNET + range 1 1 if !EXAMPLE_USE_INTERNAL_ETHERNET + default 1 + help + Set PHY address according your board schematic. endmenu diff --git a/examples/ethernet/iperf/main/cmd_ethernet.c b/examples/ethernet/iperf/main/cmd_ethernet.c index d4ae74b768..5f0fda9262 100644 --- a/examples/ethernet/iperf/main/cmd_ethernet.c +++ b/examples/ethernet/iperf/main/cmd_ethernet.c @@ -15,6 +15,7 @@ #include "esp_console.h" #include "esp_event.h" #include "esp_eth.h" +#include "driver/gpio.h" #include "argtable3/argtable3.h" #include "iperf.h" #include "sdkconfig.h" @@ -187,7 +188,11 @@ void register_ethernet(void) eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); + phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; + phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; #if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET + mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; + mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config); #if CONFIG_EXAMPLE_ETH_PHY_IP101 esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); @@ -198,28 +203,29 @@ void register_ethernet(void) #elif CONFIG_EXAMPLE_ETH_PHY_DP83848 esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config); #endif -#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET +#elif CONFIG_EXAMPLE_USE_DM9051 gpio_install_isr_service(0); spi_device_handle_t spi_handle = NULL; spi_bus_config_t buscfg = { - .miso_io_num = CONFIG_EXAMPLE_ETH_MISO_GPIO, - .mosi_io_num = CONFIG_EXAMPLE_ETH_MOSI_GPIO, - .sclk_io_num = CONFIG_EXAMPLE_ETH_SCLK_GPIO, + .miso_io_num = CONFIG_EXAMPLE_DM9051_MISO_GPIO, + .mosi_io_num = CONFIG_EXAMPLE_DM9051_MOSI_GPIO, + .sclk_io_num = CONFIG_EXAMPLE_DM9051_SCLK_GPIO, .quadwp_io_num = -1, .quadhd_io_num = -1, }; - ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1)); + ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_DM9051_SPI_HOST, &buscfg, 1)); spi_device_interface_config_t devcfg = { .command_bits = 1, .address_bits = 7, .mode = 0, - .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, - .spics_io_num = CONFIG_EXAMPLE_ETH_CS_GPIO, + .clock_speed_hz = CONFIG_EXAMPLE_DM9051_SPI_CLOCK_MHZ * 1000 * 1000, + .spics_io_num = CONFIG_EXAMPLE_DM9051_CS_GPIO, .queue_size = 20 }; - ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle)); + ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_DM9051_SPI_HOST, &devcfg, &spi_handle)); /* dm9051 ethernet driver is based on spi driver */ eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle); + dm9051_config.int_gpio_num = CONFIG_EXAMPLE_DM9051_INT_GPIO; esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config); esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config); #endif