diff --git a/examples/ethernet/ethernet/main/Kconfig.projbuild b/examples/ethernet/ethernet/main/Kconfig.projbuild new file mode 100644 index 0000000000..9591fb93ed --- /dev/null +++ b/examples/ethernet/ethernet/main/Kconfig.projbuild @@ -0,0 +1,27 @@ +menu "Example Configuration" + +choice PHY_MODEL + prompt "Select the device used for the ethernet PHY" + default CONFIG_PHY_TLK110 + help + Select the TI TLK110 or Microchip LAN8720 PHY + +config PHY_TLK110 + bool "TI TLK110 PHY" + help + Select this to use the TI TLK110 PHY + +config PHY_LAN8720 + bool "Microchip LAN8720 PHY" + help + Select this to use the Microchip LAN8720 PHY + +endchoice + +config PHY_ID + int "Enter the PHY ID (0-31) for the selected PHY model" + default 31 + help + Select the PHY ID (0-31) for the selected PHY model + +endmenu diff --git a/examples/ethernet/ethernet/main/ethernet_example_main.c b/examples/ethernet/ethernet/main/ethernet_example_main.c index d46e2e6d9c..e1f31f7fdd 100644 --- a/examples/ethernet/ethernet/main/ethernet_example_main.c +++ b/examples/ethernet/ethernet/main/ethernet_example_main.c @@ -32,11 +32,16 @@ #include "tcpip_adapter.h" #include "nvs_flash.h" #include "driver/gpio.h" + +#ifdef CONFIG_PHY_LAN8720 +#include "lan8720_phy.h" +#endif +#ifdef CONFIG_PHY_TLK110 #include "tlk110_phy.h" +#endif static const char *TAG = "eth_example"; -#define DEFAULT_PHY_CONFIG (AUTO_MDIX_ENABLE|AUTO_NEGOTIATION_ENABLE|AN_1|AN_0|LED_CFG) #define PIN_PHY_POWER 17 #define PIN_SMI_MDC 23 #define PIN_SMI_MDIO 18 @@ -57,7 +62,7 @@ eth_speed_mode_t phy_tlk110_get_speed_mode(void) return ETH_SPEED_MODE_100M; } else { return ETH_SPEED_MODE_10M; - } + } } eth_duplex_mode_t phy_tlk110_get_duplex_mode(void) @@ -66,7 +71,7 @@ eth_duplex_mode_t phy_tlk110_get_duplex_mode(void) return ETH_MDOE_FULLDUPLEX; } else { return ETH_MODE_HALFDUPLEX; - } + } } bool phy_tlk110_check_phy_link_status(void) @@ -80,7 +85,7 @@ bool phy_tlk110_get_partner_pause_enable(void) return true; } else { return false; - } + } } void phy_enable_flow_ctrl(void) @@ -90,34 +95,31 @@ void phy_enable_flow_ctrl(void) esp_eth_smi_write(AUTO_NEG_ADVERTISEMENT_REG,data|ASM_DIR|PAUSE); } -void phy_tlk110_power_enable(bool enable) +void phy_device_power_enable(bool enable) { gpio_pad_select_gpio(PIN_PHY_POWER); gpio_set_direction(PIN_PHY_POWER,GPIO_MODE_OUTPUT); if(enable == true) { gpio_set_level(PIN_PHY_POWER, 1); + ESP_LOGD(TAG, "phy_device_power_enable(TRUE)"); } else { gpio_set_level(PIN_PHY_POWER, 0); - } -} - -void phy_tlk110_init(void) -{ - esp_eth_smi_write(PHY_RESET_CONTROL_REG, SOFTWARE_RESET); - - while (esp_eth_smi_read(PHY_IDENTIFIER_REG) != OUI_MSB_21TO6_DEF) { + ESP_LOGD(TAG, "power_enable(FALSE)"); } esp_eth_smi_write(SW_STRAP_CONTROL_REG, DEFAULT_PHY_CONFIG | SW_STRAP_CONFIG_DONE); - + ets_delay_us(300); - //if config.flow_ctrl_enable == true ,enable this + //if config.flow_ctrl_enable == true ,enable this phy_enable_flow_ctrl(); } void eth_gpio_config_rmii(void) { + //crs_dv to gpio27 ,can not change (default so not needed but physical signal must be connected) + //PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO27_U, FUNC_GPIO27_EMAC_RX_DV); + //txd0 to gpio19 ,can not change PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, FUNC_GPIO19_EMAC_TXD0); //tx_en to gpio21 ,can not change @@ -131,7 +133,7 @@ void eth_gpio_config_rmii(void) //rmii clk ,can not change gpio_set_direction(0, GPIO_MODE_INPUT); - //mdc to gpio23 + //mdc to gpio23 gpio_matrix_out(PIN_SMI_MDC, EMAC_MDC_O_IDX, 0, 0); //mdio to gpio18 gpio_matrix_out(PIN_SMI_MDIO, EMAC_MDO_O_IDX, 0, 0); @@ -149,11 +151,11 @@ void eth_task(void *pvParameter) vTaskDelay(2000 / portTICK_PERIOD_MS); if (tcpip_adapter_get_ip_info(ESP_IF_ETH, &ip) == 0) { - ESP_LOGI(TAG, "\n~~~~~~~~~~~\n"); + ESP_LOGI(TAG, "~~~~~~~~~~~"); ESP_LOGI(TAG, "ETHIP:"IPSTR, IP2STR(&ip.ip)); ESP_LOGI(TAG, "ETHPMASK:"IPSTR, IP2STR(&ip.netmask)); ESP_LOGI(TAG, "ETHPGW:"IPSTR, IP2STR(&ip.gw)); - ESP_LOGI(TAG, "\n~~~~~~~~~~~\n"); + ESP_LOGI(TAG, "~~~~~~~~~~~"); } } } @@ -164,20 +166,15 @@ void app_main() tcpip_adapter_init(); esp_event_loop_init(NULL, NULL); - eth_config_t config; - config.phy_addr = PHY31; - config.mac_mode = ETH_MODE_RMII; - config.phy_init = phy_tlk110_init; +#ifdef CONFIG_PHY_LAN8720 + eth_config_t config = lan8720_default_ethernet_phy_config; +#endif +#ifdef CONFIG_PHY_TLK110 + eth_config_t config = tlk110_default_ethernet_phy_config; +#endif config.gpio_config = eth_gpio_config_rmii; config.tcpip_input = tcpip_adapter_eth_input; - config.phy_check_init = phy_tlk110_check_phy_init; - config.phy_check_link = phy_tlk110_check_phy_link_status; - config.phy_get_speed_mode = phy_tlk110_get_speed_mode; - config.phy_get_duplex_mode = phy_tlk110_get_duplex_mode; - //Only FULLDUPLEX mode support flow ctrl now! - config.flow_ctrl_enable = true; - config.phy_get_partner_pause_enable = phy_tlk110_get_partner_pause_enable; - config.phy_power_enable = phy_tlk110_power_enable; + config.phy_power_enable = phy_device_power_enable; ret = esp_eth_init(&config); diff --git a/examples/ethernet/ethernet/main/lan8720_phy.c b/examples/ethernet/ethernet/main/lan8720_phy.c new file mode 100644 index 0000000000..d5ee828da4 --- /dev/null +++ b/examples/ethernet/ethernet/main/lan8720_phy.c @@ -0,0 +1,120 @@ + +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_eth.h" + +#include "lan8720_phy.h" + +void phy_dump_lan8720_registers(); + +static const char *TAG = "lan8720"; + + +void phy_lan8720_check_phy_init(void) +{ + phy_dump_lan8720_registers(); + + while((esp_eth_smi_read(BASIC_MODE_STATUS_REG) & AUTO_NEGOTIATION_COMPLETE ) != AUTO_NEGOTIATION_COMPLETE) + {}; + while((esp_eth_smi_read(PHY_SPECIAL_CONTROL_STATUS_REG) & AUTO_NEGOTIATION_DONE ) != AUTO_NEGOTIATION_DONE) + {}; +} + +eth_speed_mode_t phy_lan8720_get_speed_mode(void) +{ + if(esp_eth_smi_read(PHY_SPECIAL_CONTROL_STATUS_REG) & SPEED_INDICATION_100T ) { + ESP_LOGD(TAG, "phy_lan8720_get_speed_mode(100)"); + return ETH_SPEED_MODE_100M; + } else { + ESP_LOGD(TAG, "phy_lan8720_get_speed_mode(10)"); + return ETH_SPEED_MODE_10M; + } +} + +eth_duplex_mode_t phy_lan8720_get_duplex_mode(void) +{ + if(esp_eth_smi_read(PHY_SPECIAL_CONTROL_STATUS_REG) & DUPLEX_INDICATION_FULL ) { + ESP_LOGD(TAG, "phy_lan8720_get_duplex_mode(FULL)"); + return ETH_MDOE_FULLDUPLEX; + } else { + ESP_LOGD(TAG, "phy_lan8720_get_duplex_mode(HALF)"); + return ETH_MODE_HALFDUPLEX; + } +} + +bool phy_lan8720_check_phy_link_status(void) +{ + if ((esp_eth_smi_read(BASIC_MODE_STATUS_REG) & LINK_STATUS) == LINK_STATUS) { + ESP_LOGD(TAG, "phy_lan8720_check_phy_link_status(UP)"); + return true; + } else { + ESP_LOGD(TAG, "phy_lan8720_check_phy_link_status(DOWN)"); + return false; + } +} + +bool phy_lan8720_get_partner_pause_enable(void) +{ + if((esp_eth_smi_read(PHY_LINK_PARTNER_ABILITY_REG) & PARTNER_PAUSE) == PARTNER_PAUSE) { + ESP_LOGD(TAG, "phy_lan8720_get_partner_pause_enable(TRUE)"); + return true; + } else { + ESP_LOGD(TAG, "phy_lan8720_get_partner_pause_enable(FALSE)"); + return false; + } +} + +void phy_enable_flow_ctrl(void) +{ + uint32_t data = 0; + data = esp_eth_smi_read(AUTO_NEG_ADVERTISEMENT_REG); + esp_eth_smi_write(AUTO_NEG_ADVERTISEMENT_REG,data|ASM_DIR|PAUSE); +} + +void phy_lan8720_init(void) +{ + ESP_LOGD(TAG, "phy_lan8720_init()"); + phy_dump_lan8720_registers(); + + esp_eth_smi_write(BASIC_MODE_CONTROL_REG, SOFTWARE_RESET); + + while (esp_eth_smi_read(PHY_IDENTIFIER_REG) != OUI_MSB_21TO6_DEF) { + } + + ets_delay_us(300); + + //if config.flow_ctrl_enable == true ,enable this + phy_enable_flow_ctrl(); +} + +const eth_config_t lan8720_default_ethernet_phy_config = { + .phy_addr = CONFIG_PHY_ID, + .mac_mode = ETH_MODE_RMII, + //Only FULLDUPLEX mode support flow ctrl now! + .flow_ctrl_enable = true, + .phy_init = phy_lan8720_init, + .phy_check_init = phy_lan8720_check_phy_init, + .phy_check_link = phy_lan8720_check_phy_link_status, + .phy_get_speed_mode = phy_lan8720_get_speed_mode, + .phy_get_duplex_mode = phy_lan8720_get_duplex_mode, + .phy_get_partner_pause_enable = phy_lan8720_get_partner_pause_enable +}; + +void phy_dump_lan8720_registers() +{ + ESP_LOGD(TAG, "LAN8720 Registers:"); + ESP_LOGD(TAG, "BCR 0x%04x", esp_eth_smi_read(0x0)); + ESP_LOGD(TAG, "BSR 0x%04x", esp_eth_smi_read(0x1)); + ESP_LOGD(TAG, "PHY1 0x%04x", esp_eth_smi_read(0x2)); + ESP_LOGD(TAG, "PHY2 0x%04x", esp_eth_smi_read(0x3)); + ESP_LOGD(TAG, "ANAR 0x%04x", esp_eth_smi_read(0x4)); + ESP_LOGD(TAG, "ANLPAR 0x%04x", esp_eth_smi_read(0x5)); + ESP_LOGD(TAG, "ANER 0x%04x", esp_eth_smi_read(0x6)); + ESP_LOGD(TAG, "MCSR 0x%04x", esp_eth_smi_read(0x17)); + ESP_LOGD(TAG, "SM 0x%04x", esp_eth_smi_read(0x18)); + ESP_LOGD(TAG, "SECR 0x%04x", esp_eth_smi_read(0x26)); + ESP_LOGD(TAG, "CSIR 0x%04x", esp_eth_smi_read(0x27)); + ESP_LOGD(TAG, "ISR 0x%04x", esp_eth_smi_read(0x29)); + ESP_LOGD(TAG, "IMR 0x%04x", esp_eth_smi_read(0x30)); + ESP_LOGD(TAG, "PSCSR 0x%04x", esp_eth_smi_read(0x31)); +} diff --git a/examples/ethernet/ethernet/main/lan8720_phy.h b/examples/ethernet/ethernet/main/lan8720_phy.h new file mode 100644 index 0000000000..76b1ac01cd --- /dev/null +++ b/examples/ethernet/ethernet/main/lan8720_phy.h @@ -0,0 +1,37 @@ +#define BASIC_MODE_CONTROL_REG (0x0) +#define SOFTWARE_RESET BIT(15) + +#define BASIC_MODE_STATUS_REG (0x1) +#define AUTO_NEGOTIATION_COMPLETE BIT(5) +#define LINK_STATUS BIT(2) + +#define PHY_IDENTIFIER_REG (0x2) +#define OUI_MSB_21TO6_DEF 0x0007 + +#define AUTO_NEG_ADVERTISEMENT_REG (0x4) +#define ASM_DIR BIT(11) +#define PAUSE BIT(10) + +#define PHY_LINK_PARTNER_ABILITY_REG (0x5) +#define PARTNER_PAUSE BIT(10) + +#define SOFTWARE_STRAP_CONTROL_REG (0x9) +#define SW_STRAP_CONFIG_DONE BIT(15) +#define AUTO_MDIX_ENABLE BIT(14) +#define AUTO_NEGOTIATION_ENABLE BIT(13) +#define AN_1 BIT(12) +#define AN_0 BIT(11) +#define LED_CFG BIT(10) +#define RMII_ENHANCED_MODE BIT(9) + +#define PHY_SPECIAL_CONTROL_STATUS_REG (0x1f) +#define AUTO_NEGOTIATION_DONE BIT(12) +#define SPEED_DUPLEX_INDICATION_10T_HALF 0x04 +#define SPEED_DUPLEX_INDICATION_10T_FULL 0x14 +#define SPEED_DUPLEX_INDICATION_100T_HALF 0x08 +#define SPEED_DUPLEX_INDICATION_100T_FULL 0x18 +#define SPEED_INDICATION_100T BIT(3) +#define SPEED_INDICATION_10T BIT(2) +#define DUPLEX_INDICATION_FULL BIT(4) + +extern const eth_config_t lan8720_default_ethernet_phy_config; diff --git a/examples/ethernet/ethernet/main/tlk110_phy.c b/examples/ethernet/ethernet/main/tlk110_phy.c new file mode 100644 index 0000000000..14c8427891 --- /dev/null +++ b/examples/ethernet/ethernet/main/tlk110_phy.c @@ -0,0 +1,145 @@ + +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_eth.h" + +#include "tlk110_phy.h" + +#define DEFAULT_PHY_CONFIG (AUTO_MDIX_ENABLE|AUTO_NEGOTIATION_ENABLE|AN_1|AN_0|LED_CFG) +void phy_dump_tlk110_registers(); + +static const char *TAG = "tlk110"; + + +void phy_tlk110_check_phy_init(void) +{ + phy_dump_tlk110_registers(); + + while((esp_eth_smi_read(BASIC_MODE_STATUS_REG) & AUTO_NEGOTIATION_COMPLETE ) != AUTO_NEGOTIATION_COMPLETE) + {}; + while((esp_eth_smi_read(PHY_STATUS_REG) & AUTO_NEGTIATION_STATUS ) != AUTO_NEGTIATION_STATUS) + {}; + while((esp_eth_smi_read(CABLE_DIAGNOSTIC_CONTROL_REG) & DIAGNOSTIC_DONE ) != DIAGNOSTIC_DONE) + {}; +} + +eth_speed_mode_t phy_tlk110_get_speed_mode(void) +{ + if((esp_eth_smi_read(PHY_STATUS_REG) & SPEED_STATUS ) != SPEED_STATUS) { + ESP_LOGD(TAG, "phy_tlk110_get_speed_mode(100)"); + return ETH_SPEED_MODE_100M; + } else { + ESP_LOGD(TAG, "phy_tlk110_get_speed_mode(10)"); + return ETH_SPEED_MODE_10M; + } +} + +eth_duplex_mode_t phy_tlk110_get_duplex_mode(void) +{ + if((esp_eth_smi_read(PHY_STATUS_REG) & DUPLEX_STATUS ) == DUPLEX_STATUS) { + ESP_LOGD(TAG, "phy_tlk110_get_duplex_mode(FULL)"); + return ETH_MDOE_FULLDUPLEX; + } else { + ESP_LOGD(TAG, "phy_tlk110_get_duplex_mode(HALF)"); + return ETH_MODE_HALFDUPLEX; + } +} + +bool phy_tlk110_check_phy_link_status(void) +{ + if ((esp_eth_smi_read(BASIC_MODE_STATUS_REG) & LINK_STATUS) == LINK_STATUS) { + ESP_LOGD(TAG, "phy_tlk110_check_phy_link_status(UP)"); + return true; + } else { + ESP_LOGD(TAG, "phy_tlk110_check_phy_link_status(DOWN)"); + return false; + } +} + +bool phy_tlk110_get_partner_pause_enable(void) +{ + if((esp_eth_smi_read(PHY_LINK_PARTNER_ABILITY_REG) & PARTNER_PAUSE) == PARTNER_PAUSE) { + ESP_LOGD(TAG, "phy_tlk110_get_partner_pause_enable(TRUE)"); + return true; + } else { + ESP_LOGD(TAG, "phy_tlk110_get_partner_pause_enable(FALSE)"); + return false; + } +} + +void phy_enable_flow_ctrl(void) +{ + uint32_t data = 0; + data = esp_eth_smi_read(AUTO_NEG_ADVERTISEMENT_REG); + esp_eth_smi_write(AUTO_NEG_ADVERTISEMENT_REG,data|ASM_DIR|PAUSE); +} + +void phy_tlk110_init(void) +{ + ESP_LOGD(TAG, "phy_tlk110_init()"); + phy_dump_tlk110_registers(); + + esp_eth_smi_write(PHY_RESET_CONTROL_REG, SOFTWARE_RESET); + + while (esp_eth_smi_read(PHY_IDENTIFIER_REG) != OUI_MSB_21TO6_DEF) { + } + + esp_eth_smi_write(SOFTWARE_STRAP_CONTROL_REG, DEFAULT_PHY_CONFIG |SW_STRAP_CONFIG_DONE); + + ets_delay_us(300); + + //if config.flow_ctrl_enable == true ,enable this + phy_enable_flow_ctrl(); +} + +const eth_config_t tlk110_default_ethernet_phy_config = { + .phy_addr = CONFIG_PHY_ID, + .mac_mode = ETH_MODE_RMII, + //Only FULLDUPLEX mode support flow ctrl now! + .flow_ctrl_enable = true, + .phy_init = phy_tlk110_init, + .phy_check_init = phy_tlk110_check_phy_init, + .phy_check_link = phy_tlk110_check_phy_link_status, + .phy_get_speed_mode = phy_tlk110_get_speed_mode, + .phy_get_duplex_mode = phy_tlk110_get_duplex_mode, + .phy_get_partner_pause_enable = phy_tlk110_get_partner_pause_enable +}; + +void phy_dump_tlk110_registers() +{ + ESP_LOGD(TAG, "TLK110 Registers:"); + ESP_LOGD(TAG, "BMCR 0x%04x", esp_eth_smi_read(0x0)); + ESP_LOGD(TAG, "BMSR 0x%04x", esp_eth_smi_read(0x1)); + ESP_LOGD(TAG, "PHYIDR1 0x%04x", esp_eth_smi_read(0x2)); + ESP_LOGD(TAG, "PHYIDR2 0x%04x", esp_eth_smi_read(0x3)); + ESP_LOGD(TAG, "ANAR 0x%04x", esp_eth_smi_read(0x4)); + ESP_LOGD(TAG, "ANLPAR 0x%04x", esp_eth_smi_read(0x5)); + ESP_LOGD(TAG, "ANER 0x%04x", esp_eth_smi_read(0x6)); + ESP_LOGD(TAG, "ANNPTR 0x%04x", esp_eth_smi_read(0x7)); + ESP_LOGD(TAG, "ANLNPTR 0x%04x", esp_eth_smi_read(0x8)); + ESP_LOGD(TAG, "SWSCR1 0x%04x", esp_eth_smi_read(0x9)); + ESP_LOGD(TAG, "SWSCR2 0x%04x", esp_eth_smi_read(0xa)); + ESP_LOGD(TAG, "SWSCR3 0x%04x", esp_eth_smi_read(0xb)); + ESP_LOGD(TAG, "REGCR 0x%04x", esp_eth_smi_read(0xd)); + ESP_LOGD(TAG, "ADDAR 0x%04x", esp_eth_smi_read(0xe)); + ESP_LOGD(TAG, "PHYSTS 0x%04x", esp_eth_smi_read(0x10)); + ESP_LOGD(TAG, "PHYSCR 0x%04x", esp_eth_smi_read(0x11)); + ESP_LOGD(TAG, "MISR1 0x%04x", esp_eth_smi_read(0x12)); + ESP_LOGD(TAG, "MISR2 0x%04x", esp_eth_smi_read(0x13)); + ESP_LOGD(TAG, "FCSCR 0x%04x", esp_eth_smi_read(0x14)); + ESP_LOGD(TAG, "RECR 0x%04x", esp_eth_smi_read(0x15)); + ESP_LOGD(TAG, "BISCR 0x%04x", esp_eth_smi_read(0x16)); + ESP_LOGD(TAG, "RBR 0x%04x", esp_eth_smi_read(0x17)); + ESP_LOGD(TAG, "LEDCR 0x%04x", esp_eth_smi_read(0x18)); + ESP_LOGD(TAG, "PHYCR 0x%04x", esp_eth_smi_read(0x19)); + ESP_LOGD(TAG, "10BTSCR 0x%04x", esp_eth_smi_read(0x1a)); + ESP_LOGD(TAG, "BICSR1 0x%04x", esp_eth_smi_read(0x1b)); + ESP_LOGD(TAG, "BICSR2 0x%04x", esp_eth_smi_read(0x1c)); + ESP_LOGD(TAG, "CDCR 0x%04x", esp_eth_smi_read(0x1e)); + ESP_LOGD(TAG, "TRXCPSR 0x%04x", esp_eth_smi_read(0x42)); + ESP_LOGD(TAG, "PWRBOCR 0x%04x", esp_eth_smi_read(0xae)); + ESP_LOGD(TAG, "VRCR 0x%04x", esp_eth_smi_read(0xD0)); + ESP_LOGD(TAG, "ALCDRR1 0x%04x", esp_eth_smi_read(0x155)); + ESP_LOGD(TAG, "CDSCR1 0x%04x", esp_eth_smi_read(0x170)); + ESP_LOGD(TAG, "CDSCR2 0x%04x", esp_eth_smi_read(0x171)); +} diff --git a/examples/ethernet/ethernet/main/tlk110_phy.h b/examples/ethernet/ethernet/main/tlk110_phy.h index 63236edebd..45ff474aaf 100644 --- a/examples/ethernet/ethernet/main/tlk110_phy.h +++ b/examples/ethernet/ethernet/main/tlk110_phy.h @@ -33,4 +33,4 @@ #define PHY_RESET_CONTROL_REG (0x1f) #define SOFTWARE_RESET BIT(15) - +extern const eth_config_t tlk110_default_ethernet_phy_config;