Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move ethernet phy support into components tree and refactor example app #398

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions components/ethernet/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,29 @@ config EMAC_TASK_PRIORITY
help
Ethernet MAC task priority.

choice PHY_MODEL
prompt "Select the device used for the ethernet PHY"
default CONFIG_PHY_TLK110
depends on ETHERNET
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
depends on ETHERNET
help
Select the PHY ID (0-31) for the selected PHY model

2 changes: 2 additions & 0 deletions components/ethernet/include/esp_eth.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ uint16_t esp_eth_smi_read(uint32_t reg_num);
*/
void esp_eth_free_rx_buf(void *buf);

extern const eth_config_t default_ethernet_phy_config;

#ifdef __cplusplus
}
#endif
Expand Down
37 changes: 37 additions & 0 deletions components/ethernet/include/lan8720_phy.h
Original file line number Diff line number Diff line change
@@ -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 default_ethernet_phy_config;
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@
#define PHY_RESET_CONTROL_REG (0x1f)
#define SOFTWARE_RESET BIT(15)


extern const eth_config_t default_ethernet_phy_config;
122 changes: 122 additions & 0 deletions components/ethernet/lan8720_phy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@

#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();
}

#ifdef CONFIG_PHY_LAN8720
const eth_config_t 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
};
#endif

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));
}
147 changes: 147 additions & 0 deletions components/ethernet/tlk110_phy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@

#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();
}

#ifdef CONFIG_PHY_TLK110
const eth_config_t 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
};
#endif

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));
}
Loading