diff --git a/components/esp32/event_default_handlers.c b/components/esp32/event_default_handlers.c index d3bf57fc89..c09775ab9d 100644 --- a/components/esp32/event_default_handlers.c +++ b/components/esp32/event_default_handlers.c @@ -22,6 +22,8 @@ #include "esp_event.h" #include "esp_event_loop.h" #include "esp_task.h" +#include "esp_eth.h" + #include "rom/ets_sys.h" #include "freertos/FreeRTOS.h" @@ -59,6 +61,11 @@ static esp_err_t system_event_sta_connected_handle_default(system_event_t *event static esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event); static esp_err_t system_event_sta_got_ip_default(system_event_t *event); +static esp_err_t system_event_eth_start_handle_default(system_event_t *event); +static esp_err_t system_event_eth_stop_handle_default(system_event_t *event); +static esp_err_t system_event_eth_connected_handle_default(system_event_t *event); +static esp_err_t system_event_eth_disconnected_handle_default(system_event_t *event); + static system_event_handle_t g_system_event_handle_table[] = { {SYSTEM_EVENT_WIFI_READY, NULL}, {SYSTEM_EVENT_SCAN_DONE, NULL}, @@ -77,9 +84,74 @@ static system_event_handle_t g_system_event_handle_table[] = { {SYSTEM_EVENT_AP_STACONNECTED, NULL}, {SYSTEM_EVENT_AP_STADISCONNECTED, NULL}, {SYSTEM_EVENT_AP_PROBEREQRECVED, NULL}, + {SYSTEM_EVENT_AP_STA_GOT_IP6, NULL}, + {SYSTEM_EVENT_ETH_START, system_event_eth_start_handle_default}, + {SYSTEM_EVENT_ETH_STOP, system_event_eth_stop_handle_default}, + {SYSTEM_EVENT_ETH_CONNECTED, system_event_eth_connected_handle_default}, + {SYSTEM_EVENT_ETH_DISCONNECTED, system_event_eth_disconnected_handle_default}, + {SYSTEM_EVENT_ETH_GOT_IP, NULL}, {SYSTEM_EVENT_MAX, NULL}, }; +esp_err_t system_event_eth_start_handle_default(system_event_t *event) +{ + tcpip_adapter_ip_info_t eth_ip; + uint8_t eth_mac[6]; + + esp_eth_get_mac(eth_mac); + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, ð_ip); + tcpip_adapter_start(TCPIP_ADAPTER_IF_ETH, eth_mac, ð_ip); + + return ESP_OK; +} + +esp_err_t system_event_eth_stop_handle_default(system_event_t *event) +{ + tcpip_adapter_stop(TCPIP_ADAPTER_IF_ETH); + + return ESP_OK; +} + +esp_err_t system_event_eth_connected_handle_default(system_event_t *event) +{ + tcpip_adapter_dhcp_status_t status; + + tcpip_adapter_up(TCPIP_ADAPTER_IF_ETH); + + tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &status); + + if (status == TCPIP_ADAPTER_DHCP_INIT) { + + tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH); + } else if (status == TCPIP_ADAPTER_DHCP_STOPPED) { + tcpip_adapter_ip_info_t eth_ip; + + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, ð_ip); + + if (!(ip4_addr_isany_val(eth_ip.ip) || ip4_addr_isany_val(eth_ip.netmask) || ip4_addr_isany_val(eth_ip.gw))) { + system_event_t evt; + + //notify event + evt.event_id = SYSTEM_EVENT_ETH_GOT_IP; + memcpy(&evt.event_info.got_ip.ip_info, ð_ip, sizeof(tcpip_adapter_ip_info_t)); + + esp_event_send(&evt); + } else { + ESP_LOGE(TAG, "invalid static ip"); + } + } + + return ESP_OK; +} + +esp_err_t system_event_eth_disconnected_handle_default(system_event_t *event) +{ + tcpip_adapter_down(TCPIP_ADAPTER_IF_ETH); + return ESP_OK; +} + + + static esp_err_t system_event_sta_got_ip_default(system_event_t *event) { WIFI_API_CALL_CHECK("esp_wifi_internal_set_sta_ip", esp_wifi_internal_set_sta_ip(), ESP_OK); @@ -97,8 +169,8 @@ esp_err_t system_event_ap_start_handle_default(system_event_t *event) tcpip_adapter_ip_info_t ap_ip; uint8_t ap_mac[6]; - WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(WIFI_IF_AP, (wifi_rxcb_t)tcpip_adapter_ap_input), ESP_OK); - WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(WIFI_IF_AP, ap_mac), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, (wifi_rxcb_t)tcpip_adapter_ap_input), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_AP, ap_mac), ESP_OK); tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ap_ip); tcpip_adapter_start(TCPIP_ADAPTER_IF_AP, ap_mac, &ap_ip); @@ -108,7 +180,7 @@ esp_err_t system_event_ap_start_handle_default(system_event_t *event) esp_err_t system_event_ap_stop_handle_default(system_event_t *event) { - WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, NULL), ESP_OK); tcpip_adapter_stop(TCPIP_ADAPTER_IF_AP); @@ -120,7 +192,7 @@ esp_err_t system_event_sta_start_handle_default(system_event_t *event) tcpip_adapter_ip_info_t sta_ip; uint8_t sta_mac[6]; - WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(WIFI_IF_STA, sta_mac), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_STA, sta_mac), ESP_OK); tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); tcpip_adapter_start(TCPIP_ADAPTER_IF_STA, sta_mac, &sta_ip); @@ -138,7 +210,7 @@ esp_err_t system_event_sta_connected_handle_default(system_event_t *event) { tcpip_adapter_dhcp_status_t status; - WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(WIFI_IF_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK); tcpip_adapter_up(TCPIP_ADAPTER_IF_STA); @@ -170,7 +242,7 @@ esp_err_t system_event_sta_connected_handle_default(system_event_t *event) esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event) { tcpip_adapter_down(TCPIP_ADAPTER_IF_STA); - WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(WIFI_IF_STA, NULL), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, NULL), ESP_OK); return ESP_OK; } @@ -267,6 +339,27 @@ static esp_err_t esp_system_event_debug(system_event_t *event) MAC2STR(ap_probereqrecved->mac)); break; } + case SYSTEM_EVENT_ETH_START: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_START"); + break; + } + case SYSTEM_EVENT_ETH_STOP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_STOP"); + break; + } + case SYSTEM_EVENT_ETH_CONNECTED: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_CONNECETED"); + break; + } + case SYSTEM_EVENT_ETH_DISCONNECTED: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_DISCONNECETED"); + break; + } + case SYSTEM_EVENT_ETH_GOT_IP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_GOT_IP"); + break; + } + default: { ESP_LOGW(TAG, "no such kind of event!"); break; diff --git a/components/esp32/include/esp_event.h b/components/esp32/include/esp_event.h index 06e35d6ad6..8e6e1833d4 100644 --- a/components/esp32/include/esp_event.h +++ b/components/esp32/include/esp_event.h @@ -45,6 +45,11 @@ typedef enum { SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */ SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ SYSTEM_EVENT_AP_STA_GOT_IP6, /**< ESP32 station or ap interface v6IP addr is preferred */ + SYSTEM_EVENT_ETH_START, /**< ESP32 ethernet start */ + SYSTEM_EVENT_ETH_STOP, /**< ESP32 ethernet stop */ + SYSTEM_EVENT_ETH_CONNECTED, /**< ESP32 ethernet phy link up */ + SYSTEM_EVENT_ETH_DISCONNECTED, /**< ESP32 ethernet phy link down */ + SYSTEM_EVENT_ETH_GOT_IP, /**< ESP32 ethernet got IP from connected AP */ SYSTEM_EVENT_MAX } system_event_id_t; diff --git a/components/esp32/include/esp_interface.h b/components/esp32/include/esp_interface.h new file mode 100644 index 0000000000..950c05bb22 --- /dev/null +++ b/components/esp32/include/esp_interface.h @@ -0,0 +1,37 @@ +// Copyright 2015-2016 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. + + +#ifndef __ESP_INTERFACE_H__ +#define __ESP_INTERFACE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ESP_IF_WIFI_STA = 0, /**< ESP32 station interface */ + ESP_IF_WIFI_AP, /**< ESP32 soft-AP interface */ + ESP_IF_ETH, /**< ESP32 ethernet interface */ + ESP_IF_MAX +} esp_interface_t; + +#ifdef __cplusplus +} +#endif + + +#endif /* __ESP_INTERFACE_TYPES_H__ */ diff --git a/components/esp32/include/esp_wifi_types.h b/components/esp32/include/esp_wifi_types.h index ca4445a487..c5dd021fe7 100644 --- a/components/esp32/include/esp_wifi_types.h +++ b/components/esp32/include/esp_wifi_types.h @@ -21,6 +21,7 @@ #include "rom/queue.h" #include "esp_err.h" #include "esp_wifi_types.h" +#include "esp_interface.h" #ifdef __cplusplus extern "C" { @@ -34,11 +35,10 @@ typedef enum { WIFI_MODE_MAX } wifi_mode_t; -typedef enum { - WIFI_IF_STA = 0, /**< ESP32 station interface */ - WIFI_IF_AP, /**< ESP32 soft-AP interface */ - WIFI_IF_MAX -} wifi_interface_t; +typedef esp_interface_t wifi_interface_t; + +#define WIFI_IF_STA ESP_IF_WIFI_STA +#define WIFI_IF_AP ESP_IF_WIFI_AP typedef enum { WIFI_COUNTRY_CN = 0, /**< country China, channel range [1, 14] */ diff --git a/components/esp32/include/soc/emac_ex_reg.h b/components/esp32/include/soc/emac_ex_reg.h new file mode 100644 index 0000000000..9b7c590966 --- /dev/null +++ b/components/esp32/include/soc/emac_ex_reg.h @@ -0,0 +1,101 @@ +// Copyright 2015-2016 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. +#ifndef _EMAC_EX_H_ +#define _EMAC_EX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc.h" +#define REG_EMAC_EX_BASE (DR_REG_EMAC_BASE + 0x800) + +#define EMAC_EX_CLKOUT_CONF_REG (REG_EMAC_EX_BASE + 0x0000) +#define EMAC_EX_CLK_OUT_DLY_NUM 0x00000003 +#define EMAC_EX_CLK_OUT_DLY_NUM_S 8 +#define EMAC_EX_CLK_OUT_H_DIV_NUM 0x0000000F +#define EMAC_EX_CLK_OUT_H_DIV_NUM_S 4 +#define EMAC_EX_CLK_OUT_DIV_NUM 0x0000000F +#define EMAC_EX_CLK_OUT_DIV_NUM_S 0 + +#define EMAC_EX_OSCCLK_CONF_REG (REG_EMAC_EX_BASE + 0x0004) +#define EMAC_EX_OSC_CLK_SEL (BIT(24)) +#define EMAC_EX_OSC_CLK_SEL_S 24 +#define EMAC_EX_OSC_H_DIV_NUM_100M 0x0000003F +#define EMAC_EX_OSC_H_DIV_NUM_100M_S 18 +#define EMAC_EX_OSC_DIV_NUM_100M 0x0000003F +#define EMAC_EX_OSC_DIV_NUM_100M_S 12 +#define EMAC_EX_OSC_H_DIV_NUM_10M 0x0000003F +#define EMAC_EX_OSC_H_DIV_NUM_10M_S 6 +#define EMAC_EX_OSC_DIV_NUM_10M 0x0000003F +#define EMAC_EX_OSC_DIV_NUM_10M_S 0 + +#define EMAC_EX_CLK_CTRL_REG (REG_EMAC_EX_BASE + 0x0008) +#define EMAC_EX_CLK_EN (BIT(5)) +#define EMAC_EX_CLK_EN_S 5 +#define EMAC_EX_MII_CLK_RX_EN (BIT(4)) +#define EMAC_EX_MII_CLK_RX_EN_S 4 +#define EMAC_EX_MII_CLK_TX_EN (BIT(3)) +#define EMAC_EX_MII_CLK_TX_EN_S 3 +#define EMAC_EX_RX_125_CLK_EN (BIT(2)) +#define EMAC_EX_RX_125_CLK_EN_S 2 +#define EMAC_EX_INT_OSC_EN (BIT(1)) +#define EMAC_EX_INT_OSC_EN_S 1 +#define EMAC_EX_EXT_OSC_EN (BIT(0)) +#define EMAC_EX_EXT_OSC_EN_S 0 + +#define EMAC_EX_PHYINF_CONF_REG (REG_EMAC_EX_BASE + 0x000c) +#define EMAC_EX_TX_ERR_OUT_EN (BIT(20)) +#define EMAC_EX_TX_ERR_OUT_EN_S 20 +#define EMAC_EX_SCR_SMI_DLY_RX_SYNC (BIT(19)) +#define EMAC_EX_SCR_SMI_DLY_RX_SYNC_S 19 +#define EMAC_EX_PMT_CTRL_EN (BIT(18)) +#define EMAC_EX_PMT_CTRL_EN_S 18 +#define EMAC_EX_SBD_CLK_GATING_EN (BIT(17)) +#define EMAC_EX_SBD_CLK_GATING_EN_S 17 +#define EMAC_EX_SS_MODE (BIT(16)) +#define EMAC_EX_SS_MODE_S 16 +#define EMAC_EX_PHY_INTF_SEL 0x00000007 +#define EMAC_EX_PHY_INTF_SEL_S 13 +#define EMAC_EX_REVMII_PHY_ADDR 0x0000001F +#define EMAC_EX_REVMII_PHY_ADDR_S 8 +#define EMAC_EX_CORE_PHY_ADDR 0x0000001F +#define EMAC_EX_CORE_PHY_ADDR_S 3 +#define EMAC_EX_SBD_FLOWCTRL (BIT(2)) +#define EMAC_EX_SBD_FLOWCTRL_S 2 +#define EMAC_EX_EXT_REVMII_RX_CLK_SEL (BIT(1)) +#define EMAC_EX_EXT_REVMII_RX_CLK_SEL_S 1 +#define EMAC_EX_INT_REVMII_RX_CLK_SEL (BIT(0)) +#define EMAC_EX_INT_REVMII_RX_CLK_SEL_S 0 + +#define EMAC_EX_PHY_INTF_RMII 4 + +#define EMAC_EX_EMAC_PD_SEL_REG (REG_EMAC_EX_BASE + 0x0010) +#define EMAC_EX_RAM_PD_EN 0x00000003 +#define EMAC_EX_RAM_PD_EN_S 0 + +#define EMAC_EX_DATE_REG (REG_EMAC_EX_BASE + 0x00fc) +#define EMAC_EX_DATE 0xFFFFFFFF +#define EMAC_EX_DATE_S 0 +#define EMAC_EX_DATE_VERSION 0x16042200 + +#define EMAC_CLK_EN_REG 0x3ff000cc +#define EMAC_CLK_EN (BIT(14)) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/esp32/include/soc/emac_reg_v2.h b/components/esp32/include/soc/emac_reg_v2.h new file mode 100644 index 0000000000..6ab1afe033 --- /dev/null +++ b/components/esp32/include/soc/emac_reg_v2.h @@ -0,0 +1,714 @@ +// Copyright 2015-2016 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. + +#ifndef _EMAC_H_ +#define _EMAC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc.h" +#define REG_EMAC_BASE DR_REG_EMAC_BASE + +#define EMAC_DMABUSMODE_REG (REG_EMAC_BASE + 0x0000) +#define EMAC_DMAREBINCRBURST (BIT(31)) +#define EMAC_DMAREBINCRBURST_S 31 +#define EMAC_DMACHANNELPRIOWT 0x00000003 +#define EMAC_DMACHANNELPRIOWT_S 28 +#define EMAC_DMATXRXPRIO (BIT(27)) +#define EMAC_DMATXRXPRIO_S 27 +#define EMAC_DMAMIXEDBURST (BIT(26)) +#define EMAC_DMAMIXEDBURST_S 26 +#define EMAC_DMAADDRALIBEA (BIT(25)) +#define EMAC_DMAADDRALIBEA_S 25 +#define EMAC_PBLX8_MODE (BIT(24)) +#define EMAC_PBLX8_MODE_S 24 +#define EMAC_USE_SEP_PBL (BIT(23)) +#define EMAC_USE_SEP_PBL_S 23 +#define EMAC_RX_DMA_PBL 0x0000003F +#define EMAC_RX_DMA_PBL_S 17 +#define EMAC_FIXED_BURST (BIT(16)) +#define EMAC_FIXED_BURST_S 16 +#define EMAC_PRI_RATIO 0x00000003 +#define EMAC_PRI_RATIO_S 14 +#define EMAC_PROG_BURST_LEN 0x0000003F +#define EMAC_PROG_BURST_LEN_S 8 +#define EMAC_ALT_DESC_SIZE (BIT(7)) +#define EMAC_ALT_DESC_SIZE_S 7 +#define EMAC_DESC_SKIP_LEN 0x0000001F +#define EMAC_DESC_SKIP_LEN_S 2 +#define EMAC_DMA_ARB_SCH (BIT(1)) +#define EMAC_DMA_ARB_SCH_S 1 +#define EMAC_SW_RST (BIT(0)) +#define EMAC_SW_RST_S 0 + +#define EMAC_DMATXPOLLDEMAND_REG (REG_EMAC_BASE + 0x0004) +#define EMAC_TRANS_POLL_DEMAND 0xFFFFFFFF +#define EMAC_TRANS_POLL_DEMAND_S 0 + +#define EMAC_DMARXPOLLDEMAND_REG (REG_EMAC_BASE + 0x0008) +#define EMAC_RECV_POLL_DEMAND 0xFFFFFFFF +#define EMAC_RECV_POLL_DEMAND_S 0 + +#define EMAC_DMARXBASEADDR_REG (REG_EMAC_BASE + 0x000C) +#define EMAC_START_RECV_LIST 0xFFFFFFFF +#define EMAC_START_RECV_LIST_S 0 + +#define EMAC_DMATXBASEADDR_REG (REG_EMAC_BASE + 0x0010) +#define EMAC_START_TRANS_LIST 0xFFFFFFFF +#define EMAC_START_TRANS_LIST_S 0 + +#define EMAC_DMASTATUS_REG (REG_EMAC_BASE + 0x0014) +#define EMAC_GMAC_LPI_INT (BIT(30)) +#define EMAC_GMAC_LPI_INT_S 30 +#define EMAC_TS_TRI_INT (BIT(29)) +#define EMAC_TS_TRI_INT_S 29 +#define EMAC_GMAC_PMT_INT (BIT(28)) +#define EMAC_GMAC_PMT_INT_S 28 +#define EMAC_GMAC_MMC_INT (BIT(27)) +#define EMAC_GMAC_MMC_INT_S 27 +#define EMAC_GMAC_LINE_INF_INT (BIT(26)) +#define EMAC_GMAC_LINE_INF_INT_S 26 +#define EMAC_ERROR_BITS 0x00000007 +#define EMAC_ERROR_BITS_S 23 +#define EMAC_TRANS_PROC_STATE 0x00000007 +#define EMAC_TRANS_PROC_STATE_S 20 +#define EMAC_RECV_PROC_STATE 0x00000007 +#define EMAC_RECV_PROC_STATE_S 17 +#define EMAC_NORM_INT_SUMM (BIT(16)) +#define EMAC_NORM_INT_SUMM_S 16 +#define EMAC_ABN_INT_SUMM (BIT(15)) +#define EMAC_ABN_INT_SUMM_S 15 +#define EMAC_EARLY_RECV_INT (BIT(14)) +#define EMAC_EARLY_RECV_INT_S 14 +#define EMAC_FATAL_BUS_ERR_INT (BIT(13)) +#define EMAC_FATAL_BUS_ERR_INT_S 13 +#define EMAC_EARLY_TRANS_INT (BIT(10)) +#define EMAC_EARLY_TRANS_INT_S 10 +#define EMAC_RECV_WDT_TO (BIT(9)) +#define EMAC_RECV_WDT_TO_S 9 +#define EMAC_RECV_PROC_STOP (BIT(8)) +#define EMAC_RECV_PROC_STOP_S 8 +#define EMAC_RECV_BUF_UNAVAIL (BIT(7)) +#define EMAC_RECV_BUF_UNAVAIL_S 7 +#define EMAC_RECV_INT (BIT(6)) +#define EMAC_RECV_INT_S 6 +#define EMAC_TRANS_UNDFLOW (BIT(5)) +#define EMAC_TRANS_UNDFLOW_S 5 +#define EMAC_RECV_OVFLOW (BIT(4)) +#define EMAC_RECV_OVFLOW_S 4 +#define EMAC_TRANS_JABBER_TO (BIT(3)) +#define EMAC_TRANS_JABBER_TO_S 3 +#define EMAC_TRANS_BUF_UNAVAIL (BIT(2)) +#define EMAC_TRANS_BUF_UNAVAIL_S 2 +#define EMAC_TRANS_PROC_STOP (BIT(1)) +#define EMAC_TRANS_PROC_STOP_S 1 +#define EMAC_TRANS_INT (BIT(0)) +#define EMAC_TRANS_INT_S 0 + +#define EMAC_DMAOPERATION_MODE_REG (REG_EMAC_BASE + 0x0018) +#define EMAC_DIS_DROP_TCPIP_CHKSUM_ERR_FRAM (BIT(26)) +#define EMAC_DIS_DROP_TCPIP_CHKSUM_ERR_FRAM_S 26 +#define EMAC_RECV_STORE_FORWARD (BIT(25)) +#define EMAC_RECV_STORE_FORWARD_S 25 +#define EMAC_DIS_FLUSH_RECV_FRAMES (BIT(24)) +#define EMAC_DIS_FLUSH_RECV_FRAMES_S 24 +#define EMAC_MSB_THRESHOLD_ACTIVATING_FLOW_CONTROL (BIT(23)) +#define EMAC_MSB_THRESHOLD_ACTIVATING_FLOW_CONTROL_S 23 +#define EMAC_MSB_THRESHOLD_DEACTIVATING_FLOW_CONTROL (BIT(22)) +#define EMAC_MSB_THRESHOLD_DEACTIVATING_FLOW_CONTROL_S 22 +#define EMAC_TRANSMIT_STORE_FORWARD (BIT(21)) +#define EMAC_TRANSMIT_STORE_FORWARD_S 21 +#define EMAC_FLUSH_TRANSMIT_FIFO (BIT(20)) +#define EMAC_FLUSH_TRANSMIT_FIFO_S 20 +#define EMAC_TRANSMIT_THRESHOLD_CONTROL 0x00000007 +#define EMAC_TRANSMIT_THRESHOLD_CONTROL_S 14 +#define EMAC_START_STOP_TRANSMISSION_COMMAND (BIT(13)) +#define EMAC_START_STOP_TRANSMISSION_COMMAND_S 13 +#define EMAC_THRESHOLD_DEACTIVATING_FLOW_CONTROL 0x00000003 +#define EMAC_THRESHOLD_DEACTIVATING_FLOW_CONTROL_S 11 +#define EMAC_THRESHOLD_ACTIVATING_FLOW_CONTROL 0x00000003 +#define EMAC_THRESHOLD_ACTIVATING_FLOW_CONTROL_S 9 +#define EMAC_ENABLE_HW_FLOW_CONTROL (BIT(8)) +#define EMAC_ENABLE_HW_FLOW_CONTROL_S 8 +#define EMAC_FORWARD_ERROR_FRAMES (BIT(7)) +#define EMAC_FORWARD_ERROR_FRAMES_S 7 +#define EMAC_FORWARD_UNDERSIZED_GOOD_FRAMES (BIT(6)) +#define EMAC_FORWARD_UNDERSIZED_GOOD_FRAMES_S 6 +#define EMAC_DROP_GIANT_FRAMES (BIT(5)) +#define EMAC_DROP_GIANT_FRAMES_S 5 +#define EMAC_RECEIVE_THRESHOLD_CONTROL 0x00000003 +#define EMAC_RECEIVE_THRESHOLD_CONTROL_S 3 +#define EMAC_OPERATE_SECOND_FRAME (BIT(2)) +#define EMAC_OPERATE_SECOND_FRAME_S 2 +#define EMAC_START_STOP_RECEIVE (BIT(1)) +#define EMAC_START_STOP_RECEIVE_S 1 + +#define EMAC_DMAINTERRUPT_EN_REG (REG_EMAC_BASE + 0x001C) +#define EMAC_NORMAL_INTERRUPT_SUMMARY_ENABLE (BIT(16)) +#define EMAC_NORMAL_INTERRUPT_SUMMARY_ENABLE_S 16 +#define EMAC_ABNORMAL_INTERRUPT_SUMMARY_ENABLE (BIT(15)) +#define EMAC_ABNORMAL_INTERRUPT_SUMMARY_ENABLE_S 15 +#define EMAC_EARLY_RECEIVE_INTERRUPT_ENABLE (BIT(14)) +#define EMAC_EARLY_RECEIVE_INTERRUPT_ENABLE_S 14 +#define EMAC_FATAL_BUS_ERROR_ENABLE (BIT(13)) +#define EMAC_FATAL_BUS_ERROR_ENABLE_S 13 +#define EMAC_EARLY_TRANSMIT_INTERRUPT_ENABLE (BIT(10)) +#define EMAC_EARLY_TRANSMIT_INTERRUPT_ENABLE_S 10 +#define EMAC_RECEIVE_WATCHDOG_TIMEOUT_ENABLE (BIT(9)) +#define EMAC_RECEIVE_WATCHDOG_TIMEOUT_ENABLE_S 9 +#define EMAC_RECEIVE_STOPPED_ENABLE (BIT(8)) +#define EMAC_RECEIVE_STOPPED_ENABLE_S 8 +#define EMAC_RECEIVE_BUFFER_UNAVAILABLE_ENABLE (BIT(7)) +#define EMAC_RECEIVE_BUFFER_UNAVAILABLE_ENABLE_S 7 +#define EMAC_RECEIVE_INTERRUPT_ENABLE (BIT(6)) +#define EMAC_RECEIVE_INTERRUPT_ENABLE_S 6 +#define EMAC_UNDERFLOW_INTERRUPT_ENABLE (BIT(5)) +#define EMAC_UNDERFLOW_INTERRUPT_ENABLE_S 5 +#define EMAC_OVERFLOW_INTERRUPT_ENABLE (BIT(4)) +#define EMAC_OVERFLOW_INTERRUPT_ENABLE_S 4 +#define EMAC_TRANSMIT_JABBER_TIMEOUT_ENABLE (BIT(3)) +#define EMAC_TRANSMIT_JABBER_TIMEOUT_ENABLE_S 3 +#define EMAC_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE (BIT(2)) +#define EMAC_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE_S 2 +#define EMAC_TRANSMIT_STOPPED_ENABLE (BIT(1)) +#define EMAC_TRANSMIT_STOPPED_ENABLE_S 1 +#define EMAC_TRANSMIT_INTERRUPT_ENABLE (BIT(0)) +#define EMAC_TRANSMIT_INTERRUPT_ENABLE_S 0 + +#define EMAC_DMAMISSEDFR_REG (REG_EMAC_BASE + 0x0020) +#define EMAC_OVERFLOW_BIT_FIFO_OVERFLOW_COUNTER (BIT(28)) +#define EMAC_OVERFLOW_BIT_FIFO_OVERFLOW_COUNTER_S 28 +#define EMAC_OVERFLOW_FRAME_COUNTER 0x000007FF +#define EMAC_OVERFLOW_FRAME_COUNTER_S 17 +#define EMAC_OVERFLOW_BIT_MISSED_FRAME_COUNTER (BIT(16)) +#define EMAC_OVERFLOW_BIT_MISSED_FRAME_COUNTER_S 16 +#define EMAC_MISSED_FRAME_COUNTER 0x0000FFFF +#define EMAC_MISSED_FRAME_COUNTER_S 0 + +#define EMAC_DMARECEIVE_INTERRUPT_WATCHDOG_TIMER_REG (REG_EMAC_BASE + 0x0024) +#define EMAC_RI_WATCHDOG_TIMER_COUNT 0x000000FF +#define EMAC_RI_WATCHDOG_TIMER_COUNT_S 0 + +#define EMAC_DMATXCURRDESC_REG (REG_EMAC_BASE + 0x0048) +#define EMAC_HOST_TRANSMIT_DESCRIPTOR_ADDRESS_POINTER 0xFFFFFFFF +#define EMAC_HOST_TRANSMIT_DESCRIPTOR_ADDRESS_POINTER_S 0 + +#define EMAC_DMARXCURRDESC_REG (REG_EMAC_BASE + 0x004C) +#define EMAC_HOST_RECEIVE_DESCRIPTOR_ADDRESS_POINTER 0xFFFFFFFF +#define EMAC_HOST_RECEIVE_DESCRIPTOR_ADDRESS_POINTER_S 0 + +#define EMAC_DMATXCURRADDR_BUF_REG (REG_EMAC_BASE + 0x0050) +#define EMAC_HOST_TRANSMIT_BUFFER_ADDRESS_POINTER 0xFFFFFFFF +#define EMAC_HOST_TRANSMIT_BUFFER_ADDRESS_POINTER_S 0 + +#define EMAC_DMARXCURRADDR_BUF_REG (REG_EMAC_BASE + 0x0054) +#define EMAC_HOST_RECEIVE_BUFFER_ADDRESS_POINTER 0xFFFFFFFF +#define EMAC_HOST_RECEIVE_BUFFER_ADDRESS_POINTER_S 0 + +#define EMAC_DMAHWFEATURE_REG (REG_EMAC_BASE + 0x0058) +#define EMAC_SELECTED_PHY_INTERFACE 0x00000007 +#define EMAC_SELECTED_PHY_INTERFACE_S 28 +#define EMAC_SOURCE_ADDRESS_VLAN_INSERTION (BIT(27)) +#define EMAC_SOURCE_ADDRESS_VLAN_INSERTION_S 27 +#define EMAC_FLEXIBLE_PULSE_PER_SECOND_OUTPUT (BIT(26)) +#define EMAC_FLEXIBLE_PULSE_PER_SECOND_OUTPUT_S 26 +#define EMAC_TIMESTAMPING_INTERNAL_SYSTEM_TIME (BIT(25)) +#define EMAC_TIMESTAMPING_INTERNAL_SYSTEM_TIME_S 25 +#define EMAC_ENHANCED_DESCRIPTOR (BIT(24)) +#define EMAC_ENHANCED_DESCRIPTOR_S 24 +#define EMAC_NUMBER_ADDITIONAL_TX_CHANNELS 0x00000003 +#define EMAC_NUMBER_ADDITIONAL_TX_CHANNELS_S 22 +#define EMAC_NUMBER_ADDITIONAL_RX_CHANNELS 0x00000003 +#define EMAC_NUMBER_ADDITIONAL_RX_CHANNELS_S 20 +#define EMAC_RXFIFOSIZE (BIT(19)) +#define EMAC_RXFIFOSIZE_S 19 +#define EMAC_IP_CHECKSUM_OFFLOAD_TYPE2 (BIT(18)) +#define EMAC_IP_CHECKSUM_OFFLOAD_TYPE2_S 18 +#define EMAC_IP_CHECKSUM_OFFLOAD_TYPE1 (BIT(17)) +#define EMAC_IP_CHECKSUM_OFFLOAD_TYPE1_S 17 +#define EMAC_CHECKSUM_OFFLOAD_TX (BIT(16)) +#define EMAC_CHECKSUM_OFFLOAD_TX_S 16 +#define EMAC_AV_FEATURE_SEL (BIT(15)) +#define EMAC_AV_FEATURE_SEL_S 15 +#define EMAC_EEE_SEL (BIT(14)) +#define EMAC_EEE_SEL_S 14 +#define EMAC_TSVER2_SEL (BIT(13)) +#define EMAC_TSVER2_SEL_S 13 +#define EMAC_TSVER1_SEL (BIT(12)) +#define EMAC_TSVER1_SEL_S 12 +#define EMAC_MMC_SEL (BIT(11)) +#define EMAC_MMC_SEL_S 11 +#define EMAC_MGK_SEL (BIT(10)) +#define EMAC_MGK_SEL_S 10 +#define EMAC_RWK_SEL (BIT(9)) +#define EMAC_RWK_SEL_S 9 +#define EMAC_SMA_SEL (BIT(8)) +#define EMAC_SMA_SEL_S 8 +#define EMAC_L3L4FLTR_EN (BIT(7)) +#define EMAC_L3L4FLTR_EN_S 7 +#define EMAC_PCS_SEL (BIT(6)) +#define EMAC_PCS_SEL_S 6 +#define EMAC_ADDMACADR_SEL (BIT(5)) +#define EMAC_ADDMACADR_SEL_S 5 +#define EMAC_HASH_SEL (BIT(4)) +#define EMAC_HASH_SEL_S 4 +#define EMAC_EXTHASH_EN (BIT(3)) +#define EMAC_EXTHASH_EN_S 3 +#define EMAC_HD_SEL (BIT(2)) +#define EMAC_HD_SEL_S 2 +#define EMAC_GMII_SEL (BIT(1)) +#define EMAC_GMII_SEL_S 1 +#define EMAC_MII_SEL (BIT(0)) +#define EMAC_MII_SEL_S 0 + +#define EMAC_DMASLOTFNCTRLSTS_REG (REG_EMAC_BASE + 0x0130) +#define EMAC_REFERENCE_SLOT_NUMBER 0x0000000F +#define EMAC_REFERENCE_SLOT_NUMBER_S 16 +#define EMAC_ADVANCE_SLOT_CHECK (BIT(1)) +#define EMAC_ADVANCE_SLOT_CHECK_S 1 +#define EMAC_ENABLE_SLOT_COMPARISON (BIT(0)) +#define EMAC_ENABLE_SLOT_COMPARISON_S 0 + +#define EMAC_DMACHANNELCTRL_REG (REG_EMAC_BASE + 0x0160) +#define EMAC_AVERAGE_BITS_PER_SLOT_INTERRUPT_ENABLE (BIT(17)) +#define EMAC_AVERAGE_BITS_PER_SLOT_INTERRUPT_ENABLE_S 17 +#define EMAC_SLOT_COUNT 0x00000007 +#define EMAC_SLOT_COUNT_S 4 +#define EMAC_CREDIT_CONTROL (BIT(1)) +#define EMAC_CREDIT_CONTROL_S 1 +#define EMAC_CREDIT_BASED_SHAPER_DISABLE (BIT(0)) +#define EMAC_CREDIT_BASED_SHAPER_DISABLE_S 0 + +#define EMAC_DMACHANNELAVSTS_REG (REG_EMAC_BASE + 0x0064) +#define EMAC_ABS_UPDATED (BIT(17)) +#define EMAC_ABS_UPDATED_S 17 +#define EMAC_AVERAGE_BITS_PER_SLOT 0x0001FFFF +#define EMAC_AVERAGE_BITS_PER_SLOT_S 0 + +#define EMAC_DMAIDLESLOPECREDIT_REG (REG_EMAC_BASE + 0x0068) +#define EMAC_IDLESLOPECREDIT 0x00003FFF +#define EMAC_IDLESLOPECREDIT_S 0 + +#define EMAC_DMASENDSLOPECREDIT_REG (REG_EMAC_BASE + 0x006C) +#define EMAC_SENDSLOPECREDIT 0x00003FFF +#define EMAC_SENDSLOPECREDIT_S 0 + +#define EMAC_DMAHIGHCREDIT_REG (REG_EMAC_BASE + 0x0070) +#define EMAC_HICREDIT 0x1FFFFFFF +#define EMAC_HICREDIT_S 0 + +#define EMAC_DMALOCREDIT_REG (REG_EMAC_BASE + 0x0074) +#define EMAC_LOCREDIT 0x1FFFFFFF +#define EMAC_LOCREDIT_S 0 + +#define EMAC_GMACCONFIG_REG (REG_EMAC_BASE + 0x1000) +#define EMAC_SOURCE_ADDRESS_INSERTION_REPLACEMENT_CONTROL 0x00000007 +#define EMAC_SOURCE_ADDRESS_INSERTION_REPLACEMENT_CONTROL_S 28 +#define EMAC_AS_SUPPORT_2K_PACKETS (BIT(27)) +#define EMAC_AS_SUPPORT_2K_PACKETS_S 27 +#define EMAC_SMII_FORCE_TRANSMIT_ERROR (BIT(26)) +#define EMAC_SMII_FORCE_TRANSMIT_ERROR_S 26 +#define EMAC_CRC_STRIPPING_TYPE_FRAMES (BIT(25)) +#define EMAC_CRC_STRIPPING_TYPE_FRAMES_S 25 +#define EMAC_TRANSMIT_CONFIGURATION (BIT(24)) +#define EMAC_TRANSMIT_CONFIGURATION_S 24 +#define EMAC_GMACWATCHDOG (BIT(23)) +#define EMAC_GMACWATCHDOG_S 23 +#define EMAC_GMACJABBER (BIT(22)) +#define EMAC_GMACJABBER_S 22 +#define EMAC_GMACFRAMEBURST (BIT(21)) +#define EMAC_GMACFRAMEBURST_S 21 +#define EMAC_GMACJUMBOFRAME (BIT(20)) +#define EMAC_GMACJUMBOFRAME_S 20 +#define EMAC_GMACINTERFRAMEGAP 0x00000007 +#define EMAC_GMACINTERFRAMEGAP_S 17 +#define EMAC_GMACDISABLECRS (BIT(16)) +#define EMAC_GMACDISABLECRS_S 16 +#define EMAC_GMACMIIGMII (BIT(15)) +#define EMAC_GMACMIIGMII_S 15 +#define EMAC_GMACFESPEED (BIT(14)) +#define EMAC_GMACFESPEED_S 14 +#define EMAC_GMACRXOWN (BIT(13)) +#define EMAC_GMACRXOWN_S 13 +#define EMAC_GMACLOOPBACK (BIT(12)) +#define EMAC_GMACLOOPBACK_S 12 +#define EMAC_GMACDUPLEX (BIT(11)) +#define EMAC_GMACDUPLEX_S 11 +#define EMAC_GMACRXIPCOFFLOAD (BIT(10)) +#define EMAC_GMACRXIPCOFFLOAD_S 10 +#define EMAC_GMACRETRY (BIT(9)) +#define EMAC_GMACRETRY_S 9 +#define EMAC_GMACLINK (BIT(8)) +#define EMAC_GMACLINK_S 8 +#define EMAC_GMACPADCRCSTRIP (BIT(7)) +#define EMAC_GMACPADCRCSTRIP_S 7 +#define EMAC_GMACBACKOFFLIMIT 0x00000003 +#define EMAC_GMACBACKOFFLIMIT_S 5 +#define EMAC_GMACDEFERRALCHECK (BIT(4)) +#define EMAC_GMACDEFERRALCHECK_S 4 +#define EMAC_GMACTX (BIT(3)) +#define EMAC_GMACTX_S 3 +#define EMAC_GMACRX (BIT(2)) +#define EMAC_GMACRX_S 2 +#define EMAC_PREAMBLE_LENGTH_TRANSMIT_FRAMES 0x00000003 +#define EMAC_PREAMBLE_LENGTH_TRANSMIT_FRAMES_S 0 + +#define EMAC_GMACFRAMEFILTER_REG (REG_EMAC_BASE + 0x1004) +#define EMAC_RECEIVEALL (BIT(31)) +#define EMAC_RECEIVEALL_S 31 +#define EMAC_DROP_NON_TCP_UDP_IP_FRAMES (BIT(21)) +#define EMAC_DROP_NON_TCP_UDP_IP_FRAMES_S 21 +#define EMAC_LAYER_3_AND_LAYER_4_FILTER_ENABLE (BIT(20)) +#define EMAC_LAYER_3_AND_LAYER_4_FILTER_ENABLE_S 20 +#define EMAC_VLAN_TAG_FILTER_ENABLE (BIT(16)) +#define EMAC_VLAN_TAG_FILTER_ENABLE_S 16 +#define EMAC_HASH_OR_PERFECT_FILTE (BIT(10)) +#define EMAC_HASH_OR_PERFECT_FILTE_S 10 +#define EMAC_SOURCE_ADDRESS_FILTER_ENABLE (BIT(9)) +#define EMAC_SOURCE_ADDRESS_FILTER_ENABLE_S 9 +#define EMAC_SA_INVERSE_FILTERING (BIT(8)) +#define EMAC_SA_INVERSE_FILTERING_S 8 +#define EMAC_PASS_CONTROL_FRAMES 0x00000003 +#define EMAC_PASS_CONTROL_FRAMES_S 6 +#define EMAC_DISABLE_BROADCAST_FRAMES (BIT(5)) +#define EMAC_DISABLE_BROADCAST_FRAMES_S 5 +#define EMAC_PASS_ALL_MULTICAST (BIT(4)) +#define EMAC_PASS_ALL_MULTICAST_S 4 +#define EMAC_DA_INVERSE_FILTERING (BIT(3)) +#define EMAC_DA_INVERSE_FILTERING_S 3 +#define EMAC_HASH_MULTICAST (BIT(2)) +#define EMAC_HASH_MULTICAST_S 2 +#define EMAC_HASH_UNICAST (BIT(1)) +#define EMAC_HASH_UNICAST_S 1 +#define EMAC_PROMISCUOUS_MODE (BIT(0)) +#define EMAC_PROMISCUOUS_MODE_S 0 + +#define EMAC_GMACHASHHIGH_REG (REG_EMAC_BASE + 0x1008) +#define EMAC_HASH_TABLE_HIGH 0xFFFFFFFF +#define EMAC_HASH_TABLE_HIGH_S 0 + +#define EMAC_GMACHASHLOW_REG (REG_EMAC_BASE + 0x100C) +#define EMAC_HASH_TABLE_LOW 0xFFFFFFFF +#define EMAC_HASH_TABLE_LOW_S 0 + +#define EMAC_GMACGMIIADDR_REG (REG_EMAC_BASE + 0x1010) +#define EMAC_GMIIDEV 0x0000001F +#define EMAC_GMIIDEV_S 11 +#define EMAC_GMIIREG 0x0000001F +#define EMAC_GMIIREG_S 6 +#define EMAC_GMIICSRCLK 0x0000000F +#define EMAC_GMIICSRCLK_S 2 +#define EMAC_GMIIWRITE (BIT(1)) +#define EMAC_GMIIWRITE_S 1 +#define EMAC_GMIIBUSY (BIT(0)) +#define EMAC_GMIIBUSY_S 0 + +#define EMAC_GMACGMIIDATA_REG (REG_EMAC_BASE + 0x1014) +#define EMAC_GMII_DATA 0x0000FFFF +#define EMAC_GMII_DATA_S 0 + +#define EMAC_GMACFLOWCONTROL_REG (REG_EMAC_BASE + 0x1018) +#define EMAC_PAUSE_TIME 0x0000FFFF +#define EMAC_PAUSE_TIME_S 16 +#define EMAC_DISABLE_ZERO_QUANTA_PAUSE (BIT(7)) +#define EMAC_DISABLE_ZERO_QUANTA_PAUSE_S 7 +#define EMAC_PAUSE_LOW_THRESHOLD 0x00000003 +#define EMAC_PAUSE_LOW_THRESHOLD_S 4 +#define EMAC_UNICAST_PAUSE_FRAME_DETECT (BIT(3)) +#define EMAC_UNICAST_PAUSE_FRAME_DETECT_S 3 +#define EMAC_RECEIVE_FLOW_CONTROL_ENABLE (BIT(2)) +#define EMAC_RECEIVE_FLOW_CONTROL_ENABLE_S 2 +#define EMAC_TRANSMIT_FLOW_CONTROL_ENABLE (BIT(1)) +#define EMAC_TRANSMIT_FLOW_CONTROL_ENABLE_S 1 +#define EMAC_FLOW_CONTROL_BUSY_BACKPRESSURE_ACTIVATE (BIT(0)) +#define EMAC_FLOW_CONTROL_BUSY_BACKPRESSURE_ACTIVATE_S 0 + +#define EMAC_GMACVLAN_REG (REG_EMAC_BASE + 0x101C) +#define EMAC_VLAN_TAG_HASH_TABLE_MATCH_ENABLE (BIT(19)) +#define EMAC_VLAN_TAG_HASH_TABLE_MATCH_ENABLE_S 19 +#define EMAC_ENABLE_S_VLAN (BIT(18)) +#define EMAC_ENABLE_S_VLAN_S 18 +#define EMAC_VLAN_TAG_INVERSE_MATCH_ENABLE (BIT(17)) +#define EMAC_VLAN_TAG_INVERSE_MATCH_ENABLE_S 17 +#define EMAC_ENABLE_VLAN_TAG_COMPARISON (BIT(16)) +#define EMAC_ENABLE_VLAN_TAG_COMPARISON_S 16 +#define EMAC_VLAN_TAG_IDENTIFIER_RECEIVE_FRAMES 0x0000FFFF +#define EMAC_VLAN_TAG_IDENTIFIER_RECEIVE_FRAMES_S 0 + +#define EMAC_GMACVERSION_REG (REG_EMAC_BASE + 0x1020) +#define EMAC_USERVER 0x000000FF +#define EMAC_USERVER_S 8 +#define EMAC_SNPSVER 0x000000FF +#define EMAC_SNPSVER_S 0 + +#define EMAC_GMACDEBUG_REG (REG_EMAC_BASE + 0x1024) +#define EMAC_MTL_TXSTATUS_FIFO_FULL_STATUS (BIT(25)) +#define EMAC_MTL_TXSTATUS_FIFO_FULL_STATUS_S 25 +#define EMAC_MTL_TX_FIFO_NOT_EMPTY_STATUS (BIT(24)) +#define EMAC_MTL_TX_FIFO_NOT_EMPTY_STATUS_S 24 +#define EMAC_MTL_TX_FIFO_WRITE_CONTROLLER_STATUS (BIT(22)) +#define EMAC_MTL_TX_FIFO_WRITE_CONTROLLER_STATUS_S 22 +#define EMAC_MTL_TX_FIFO_READ_CONTROLLER_STATUS 0x00000003 +#define EMAC_MTL_TX_FIFO_READ_CONTROLLER_STATUS_S 20 +#define EMAC_MAC_TRANSMITTER_PAUSE (BIT(19)) +#define EMAC_MAC_TRANSMITTER_PAUSE_S 19 +#define EMAC_MAC_TRANSMIT_FRAME_CONTROLLER_STATUS 0x00000003 +#define EMAC_MAC_TRANSMIT_FRAME_CONTROLLER_STATUS_S 17 +#define EMAC_MAC_TRANSMIT_PROTOCOL_ENGINE_STATUS (BIT(16)) +#define EMAC_MAC_TRANSMIT_PROTOCOL_ENGINE_STATUS_S 16 +#define EMAC_MTL_RXFIFO_FILL_LEVEL_STATUS 0x00000003 +#define EMAC_MTL_RXFIFO_FILL_LEVEL_STATUS_S 8 +#define EMAC_MTL_RXFIFO_READ_CONTROLLER_STATE 0x00000003 +#define EMAC_MTL_RXFIFO_READ_CONTROLLER_STATE_S 5 +#define EMAC_MTL_RX_FIFO_WRITE_CONTROLLER_ACTIVE_STATUS (BIT(4)) +#define EMAC_MTL_RX_FIFO_WRITE_CONTROLLER_ACTIVE_STATUS_S 4 +#define EMAC_MAC_RECEIVE_FRAME_FIFO_CONTROLLER_STATUS 0x00000003 +#define EMAC_MAC_RECEIVE_FRAME_FIFO_CONTROLLER_STATUS_S 1 +#define EMAC_MAC_RECEIVE_PROTOCOL_ENGINE_STATUS (BIT(0)) +#define EMAC_MAC_RECEIVE_PROTOCOL_ENGINE_STATUS_S 0 + +#define EMAC_GMACLPITIMERSCONTROL_REG (REG_EMAC_BASE + 0x1034) +#define EMAC_LPI_LS_TIMER 0x000003FF +#define EMAC_LPI_LS_TIMER_S 16 +#define EMAC_LPI_TW_TIMER 0x0000FFFF +#define EMAC_LPI_TW_TIMER_S 0 + +#define EMAC_GMACINTERRUPTSTATUS_REG (REG_EMAC_BASE + 0x1038) +#define EMAC_GPI_INTERRUPT_STATUS (BIT(11)) +#define EMAC_GPI_INTERRUPT_STATUS_S 11 +#define EMAC_LPI_INTERRUPT_STATUS (BIT(10)) +#define EMAC_LPI_INTERRUPT_STATUS_S 10 +#define EMAC_TIMESTAMP_INTERRUP_STATUS (BIT(9)) +#define EMAC_TIMESTAMP_INTERRUP_STATUS_S 9 +#define EMAC_MMC_RECEIVE_CHECKSUM_OFFLOAD_INTERRUPT_STATUS (BIT(7)) +#define EMAC_MMC_RECEIVE_CHECKSUM_OFFLOAD_INTERRUPT_STATUS_S 7 +#define EMAC_MMC_TRANSMIT_INTERRUPT_STATUS (BIT(6)) +#define EMAC_MMC_TRANSMIT_INTERRUPT_STATUS_S 6 +#define EMAC_MMC_RECEIVE_INTERRUPT_STATUS (BIT(5)) +#define EMAC_MMC_RECEIVE_INTERRUPT_STATUS_S 5 +#define EMAC_MMC_INTERRUPT_STATUS (BIT(4)) +#define EMAC_MMC_INTERRUPT_STATUS_S 4 +#define EMAC_PMT_INTERRUPT_STATUS (BIT(3)) +#define EMAC_PMT_INTERRUPT_STATUS_S 3 +#define EMAC_PCS_AUTO_NEGOTIATION_COMPLETE (BIT(2)) +#define EMAC_PCS_AUTO_NEGOTIATION_COMPLETE_S 2 +#define EMAC_PCS_LINK_STATUS_CHANGED (BIT(1)) +#define EMAC_PCS_LINK_STATUS_CHANGED_S 1 +#define EMAC_INTERRUPT_STATUS (BIT(0)) +#define EMAC_INTERRUPT_STATUS_S 0 + +#define EMAC_GMACINTERRUPTMASK_REG (REG_EMAC_BASE + 0x103C) +#define EMAC_LPI_INTERRUPT_MASK (BIT(10)) +#define EMAC_LPI_INTERRUPT_MASK_S 10 +#define EMAC_TIMESTAMP_INTERRUPT_MASK (BIT(9)) +#define EMAC_TIMESTAMP_INTERRUPT_MASK_S 9 +#define EMAC_PMT_INTERRUPT_MASK (BIT(3)) +#define EMAC_PMT_INTERRUPT_MASK_S 3 +#define EMAC_PCS_AN_COMPLETION_INTERRUPT_MASK (BIT(2)) +#define EMAC_PCS_AN_COMPLETION_INTERRUPT_MASK_S 2 +#define EMAC_PCS_LINK_STATUS_INTERRUPT_MASK (BIT(1)) +#define EMAC_PCS_LINK_STATUS_INTERRUPT_MASK_S 1 +#define EMAC_INTERRUPT_MASK (BIT(0)) +#define EMAC_INTERRUPT_MASK_S 0 + +#define EMAC_GMACADDR0HIGH_REG (REG_EMAC_BASE + 0x1040) +#define EMAC_ADDRESS_ENABLE0 (BIT(31)) +#define EMAC_ADDRESS_ENABLE0_S 31 +#define EMAC_MAC_ADDRESS0_HI 0x0000FFFF +#define EMAC_MAC_ADDRESS0_HI_S 0 + +#define EMAC_GMACADDR0LOW_REG (REG_EMAC_BASE + 0x1044) +#define EMAC_MAC_ADDRESS0_LOW 0xFFFFFFFF +#define EMAC_MAC_ADDRESS0_LOW_S 0 + +#define EMAC_GMACADDR1HIGH_REG (REG_EMAC_BASE + 0x1048) +#define EMAC_ADDRESS_ENABLE1 (BIT(31)) +#define EMAC_ADDRESS_ENABLE1_S 31 +#define EMAC_SOURCE_ADDRESS (BIT(30)) +#define EMAC_SOURCE_ADDRESS_S 30 +#define EMAC_MASK_BYTE_CONTROL 0x0000003F +#define EMAC_MASK_BYTE_CONTROL_S 24 +#define EMAC_MAC_ADDRESS1_HI 0x0000FFFF +#define EMAC_MAC_ADDRESS1_HI_S 0 + +#define EMAC_GMACADDR1LOW_REG (REG_EMAC_BASE + 0x104C) +#define EMAC_MAC_ADDRESS1_LOW 0xFFFFFFFF +#define EMAC_MAC_ADDRESS1_LOW_S 0 + +#define EMAC_GMAC_AN_CONTROL_REG (REG_EMAC_BASE + 0x10C0) +#define EMAC_SGMII_RAL_CONTROL (BIT(18)) +#define EMAC_SGMII_RAL_CONTROL_S 18 +#define EMAC_LOCK_REFERENCE (BIT(17)) +#define EMAC_LOCK_REFERENCE_S 17 +#define EMAC_ENABLE_COMMA_DETECT (BIT(16)) +#define EMAC_ENABLE_COMMA_DETECT_S 16 +#define EMAC_EXTERNAL_LOOPBACK_ENABLE (BIT(14)) +#define EMAC_EXTERNAL_LOOPBACK_ENABLE_S 14 +#define EMAC_AUTO_NEGOTIATION_ENABLE (BIT(12)) +#define EMAC_AUTO_NEGOTIATION_ENABLE_S 12 +#define EMAC_RESTART_AUTO_NEGOTIATION (BIT(9)) +#define EMAC_RESTART_AUTO_NEGOTIATION_S 9 + +#define EMAC_GMAC_AN_STATUS_REG (REG_EMAC_BASE + 0x10C4) +#define EMAC_EXTENDED_STATUS (BIT(8)) +#define EMAC_EXTENDED_STATUS_S 8 +#define EMAC_AUTO_NEGOTIATION_COMPLETE (BIT(5)) +#define EMAC_AUTO_NEGOTIATION_COMPLETE_S 5 +#define EMAC_AUTO_NEGOTIATION_ABILITY (BIT(3)) +#define EMAC_AUTO_NEGOTIATION_ABILITY_S 3 +#define EMAC_LINK_AN_STATUS (BIT(2)) +#define EMAC_LINK_AN_STATUS_S 2 + +#define EMAC_GMAC_AUTO_NEGOTIATION_ADVERTISEMENT_REG (REG_EMAC_BASE + 0x10C8) +#define EMAC_ADV_NEXT_PAGE_SUPPORT (BIT(15)) +#define EMAC_ADV_NEXT_PAGE_SUPPORT_S 15 +#define EMAC_ADV_REMOTE_FAULT_ENCODING 0x00000003 +#define EMAC_ADV_REMOTE_FAULT_ENCODING_S 12 +#define EMAC_ADV_PAUSE_ENCODING 0x00000003 +#define EMAC_ADV_PAUSE_ENCODING_S 7 +#define EMAC_ADV_HALF_DUPLEX (BIT(6)) +#define EMAC_ADV_HALF_DUPLEX_S 6 +#define EMAC_ADV_FULL_DUPLEX (BIT(5)) +#define EMAC_ADV_FULL_DUPLEX_S 5 + +#define EMAC_GMAC_AUTO_NEGOTIATION_LINK_PARTNER_ABILITY_REG (REG_EMAC_BASE + 0x10CC) +#define EMAC_LINK_NEXT_PAGE_SUPPORT (BIT(15)) +#define EMAC_LINK_NEXT_PAGE_SUPPORT_S 15 +#define EMAC_LINK_ACKNOWLEDGE (BIT(14)) +#define EMAC_LINK_ACKNOWLEDGE_S 14 +#define EMAC_LINK_REMOTE_FAULT_ENCODING 0x00000003 +#define EMAC_LINK_REMOTE_FAULT_ENCODING_S 12 +#define EMAC_LINK_PAUSE_ENCODING 0x00000003 +#define EMAC_LINK_PAUSE_ENCODING_S 7 +#define EMAC_LINK_HALF_DUPLEX (BIT(6)) +#define EMAC_LINK_HALF_DUPLEX_S 6 +#define EMAC_LINK_FULL_DUPLEX (BIT(5)) +#define EMAC_LINK_FULL_DUPLEX_S 5 + +#define EMAC_GMAC_AUTO_NEGOTIATION_EXPANSION_REG (REG_EMAC_BASE + 0x10D0) +#define EMAC_NEXT_PAGE_ABILITY (BIT(2)) +#define EMAC_NEXT_PAGE_ABILITY_S 2 +#define EMAC_NEW_PAGE_RECEIVED (BIT(1)) +#define EMAC_NEW_PAGE_RECEIVED_S 1 + +#define EMAC_GMAC_TBI_EXTENDED_STATUS_REG (REG_EMAC_BASE + 0x10D4) +#define EMAC_1000BASE_X_FULL_DUPLEX_CAPABLE (BIT(15)) +#define EMAC_1000BASE_X_FULL_DUPLEX_CAPABLE_S 15 +#define EMAC_1000BASE_X_HALF_DUPLEX_CAPABLE (BIT(14)) +#define EMAC_1000BASE_X_HALF_DUPLEX_CAPABLE_S 14 + +#define EMAC_GMAC_CONTROL_STATUS_REG (REG_EMAC_BASE + 0x10D8) +#define EMAC_SMIDRXS (BIT(16)) +#define EMAC_SMIDRXS_S 16 +#define EMAC_FALSE_CARRIER_DETECTED (BIT(5)) +#define EMAC_FALSE_CARRIER_DETECTED_S 5 +#define EMAC_JABBER_TIMEOUT (BIT(4)) +#define EMAC_JABBER_TIMEOUT_S 4 +#define EMAC_LINK_STATUS (BIT(3)) +#define EMAC_LINK_STATUS_S 3 +#define EMAC_LINK_SPEED 0x00000003 +#define EMAC_LINK_SPEED_S 1 +#define EMAC_LINK_MODE (BIT(0)) +#define EMAC_LINK_MODE_S 0 + +#define EMAC_GMAC_WATCHDOG_TIMEOUT_REG (REG_EMAC_BASE + 0x10DC) +#define EMAC_PROGRAMMABLE_WATCHDOG_ENABLE (BIT(16)) +#define EMAC_PROGRAMMABLE_WATCHDOG_ENABLE_S 16 +#define EMAC_WATCHDOG_TIMEOUT 0x00003FFF +#define EMAC_WATCHDOG_TIMEOUT_S 0 + +#define EMAC_GMAC_GENERAL_PURPOSE_IO_REG (REG_EMAC_BASE + 0x10E0) +#define EMAC_GPI_TYPE 0x0000000F +#define EMAC_GPI_TYPE_S 24 +#define EMAC_GPI_INTERRUPT_ENABLE 0x0000000F +#define EMAC_GPI_INTERRUPT_ENABLE_S 16 +#define EMAC_GENERAL_PURPOSE_OUTPUT 0x0000000F +#define EMAC_GENERAL_PURPOSE_OUTPUT_S 8 +#define EMAC_GENERAL_PURPOSE_INPUT_STATUS 0x0000000F +#define EMAC_GENERAL_PURPOSE_INPUT_STATUS_S 0 + +#define EMAC_GMAC_LAYER3_LAYER4_CONTROL0_REG (REG_EMAC_BASE + 0x1400) +#define EMAC_LAYER4_DESTINATION_PORT_INVERSE_MATCH_ENABLE (BIT(21)) +#define EMAC_LAYER4_DESTINATION_PORT_INVERSE_MATCH_ENABLE_S 21 +#define EMAC_LAYER4_DESTINATION_PORT_MATCH_ENABLE (BIT(20)) +#define EMAC_LAYER4_DESTINATION_PORT_MATCH_ENABLE_S 20 +#define EMAC_LAYER4_SOURCE_PORT_INVERSE_MATCH_ENABLE (BIT(19)) +#define EMAC_LAYER4_SOURCE_PORT_INVERSE_MATCH_ENABLE_S 19 +#define EMAC_LAYER4_SOURCE_PORT_MATCH_ENABLE (BIT(18)) +#define EMAC_LAYER4_SOURCE_PORT_MATCH_ENABLE_S 18 +#define EMAC_LAYER4_PROTOCOL_ENABLE (BIT(16)) +#define EMAC_LAYER4_PROTOCOL_ENABLE_S 16 +#define EMAC_LAYER3_IP_DA_HIGHER_BITS_MATCH 0x0000001F +#define EMAC_LAYER3_IP_DA_HIGHER_BITS_MATCH_S 11 +#define EMAC_LAYER3_IP_SA_HIGHER_BITS_MATCH 0x0000001F +#define EMAC_LAYER3_IP_SA_HIGHER_BITS_MATCH_S 6 +#define EMAC_LAYER3_IP_DA_INVERSE_MATCH_ENABLE (BIT(5)) +#define EMAC_LAYER3_IP_DA_INVERSE_MATCH_ENABLE_S 5 +#define EMAC_LAYER3_IP_DA_MATCH_ENABLE (BIT(4)) +#define EMAC_LAYER3_IP_DA_MATCH_ENABLE_S 4 +#define EMAC_LAYER3_IP_SA_INVERSE_MATCH_ENABLE (BIT(3)) +#define EMAC_LAYER3_IP_SA_INVERSE_MATCH_ENABLE_S 3 +#define EMAC_LAYER3_IP_SA_MATCH_ENABLE (BIT(2)) +#define EMAC_LAYER3_IP_SA_MATCH_ENABLE_S 2 +#define EMAC_LAYER3_PROTOCOL_ENABLE (BIT(0)) +#define EMAC_LAYER3_PROTOCOL_ENABLE_S 0 + +#define EMAC_GMAC_LAYER4_ADDRESS0_REG (REG_EMAC_BASE + 0x1404) +#define EMAC_LAYER4_DESTINATION_PORT_NUMBER_FIELD 0x0000FFFF +#define EMAC_LAYER4_DESTINATION_PORT_NUMBER_FIELD_S 16 +#define EMAC_LAYER4_SOURCE_PORT_NUMBER_FIELD 0x0000FFFF +#define EMAC_LAYER4_SOURCE_PORT_NUMBER_FIELD_S 0 + +#define EMAC_GMAC_LAYER3_ADDRESS0_REG (REG_EMAC_BASE + 0x1410) +#define EMAC_LAYER3_ADDRESS0_FIELD 0xFFFFFFFF +#define EMAC_LAYER3_ADDRESS0_FIELD_S 0 + +#define EMAC_GMAC_LAYER3_ADDRESS1_REG (REG_EMAC_BASE + 0x1414) +#define EMAC_LAYER3_ADDRESS1_FIELD 0xFFFFFFFF +#define EMAC_LAYER3_ADDRESS1_FIELD_S 0 + +#define EMAC_GMAC_LAYER3_ADDRESS2_REG (REG_EMAC_BASE + 0x1418) +#define EMAC_LAYER3_ADDRESS2_FIELD 0xFFFFFFFF +#define EMAC_LAYER3_ADDRESS2_FIELD_S 0 + +#define EMAC_GMAC_LAYER3_ADDRESS3_REG (REG_EMAC_BASE + 0x141C) +#define EMAC_LAYER3_ADDRESS3_FIELD 0xFFFFFFFF +#define EMAC_LAYER3_ADDRESS3_FIELD_S 0 + +#define EMAC_GMAC_HASH_TABLE0_REG (REG_EMAC_BASE + 0x1500) +#define EMAC_FIRST32_BITS_HASH_TABLE 0xFFFFFFFF +#define EMAC_FIRST32_BITS_HASH_TABLE_S 0 + +#define EMAC_GMAC_VLAN_TAG_INCLUSION_REPLACEMENT_REG (REG_EMAC_BASE + 0x1584) +#define EMAC_VLAN_C_VLAN_S_VLAN (BIT(19)) +#define EMAC_VLAN_C_VLAN_S_VLAN_S 19 +#define EMAC_VLAN_PRIORITY_CONTROL (BIT(18)) +#define EMAC_VLAN_PRIORITY_CONTROL_S 18 +#define EMAC_VLAN_TAG_CONTROL_TRANSMIT_FRAMES 0x00000003 +#define EMAC_VLAN_TAG_CONTROL_TRANSMIT_FRAMES_S 16 +#define EMAC_VLAN_TAG_TRANSMIT_FRAMES 0x0000FFFF +#define EMAC_VLAN_TAG_TRANSMIT_FRAMES_S 0 + +#define EMAC_GMAC_VLAN_HASH_TABLE_REG (REG_EMAC_BASE + 0x1588) +#define EMAC_VLAN_HASH_TABLE 0x0000FFFF +#define EMAC_VLAN_HASH_TABLE_S 0 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/esp32/include/soc/soc.h b/components/esp32/include/soc/soc.h index 5781b4c85e..c80b518292 100755 --- a/components/esp32/include/soc/soc.h +++ b/components/esp32/include/soc/soc.h @@ -271,7 +271,7 @@ * 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1) * 7 1 software Reserved Reserved * 8 1 extern level BLE Controller - * 9 1 extern level + * 9 1 extern level EMAC * 10 1 extern edge Internal Timer * 11 3 profiling * 12 1 extern level @@ -303,6 +303,7 @@ #define ETS_FROM_CPU_INUM 2 #define ETS_T0_WDT_INUM 3 #define ETS_WBB_INUM 4 +#define ETS_EMAC_INUM 9 #define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/ #define ETS_FRC1_INUM 22 #define ETS_T1_WDT_INUM 24 diff --git a/components/ethernet/Kconfig b/components/ethernet/Kconfig new file mode 100644 index 0000000000..cbd3bfbe47 --- /dev/null +++ b/components/ethernet/Kconfig @@ -0,0 +1,20 @@ +menuconfig ETHERNET + bool "Enable Ethernet" + default n + help + Enable this option to enable ethernet driver and show the menu with ethernet features. + + +config DMA_RX_BUF_NUM + int "Dma Rx Buf Num" + default 10 + depends on ETHERNET + help + Dma rx buf num ,can not be 0 . + +config DMA_TX_BUF_NUM + int "Dma Tx Buf Num" + default 10 + depends on ETHERNET + help + Dma tx Buf num ,can not be 0. diff --git a/components/ethernet/component.mk b/components/ethernet/component.mk new file mode 100755 index 0000000000..c2c4c03a1a --- /dev/null +++ b/components/ethernet/component.mk @@ -0,0 +1,5 @@ +# +# Component Makefile +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/components/ethernet/emac_common.h b/components/ethernet/emac_common.h new file mode 100644 index 0000000000..48f71fd90f --- /dev/null +++ b/components/ethernet/emac_common.h @@ -0,0 +1,125 @@ +// Copyright 2015-2016 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. + +#ifndef _EMAC_COMMON_H_ +#define _EMAC_COMMON_H_ + +#include + +#include "esp_err.h" +#include "emac_dev.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint32_t emac_sig_t; +typedef uint32_t emac_par_t; + +typedef struct { + emac_sig_t sig; + emac_par_t par; +} emac_event_t; + +enum emac_mode { + EMAC_MODE_RMII = 0, + EMAC_MDOE_MII, +}; + +enum emac_runtime_status { + EMAC_RUNTIME_NOT_INIT = 0, + EMAC_RUNTIME_INIT, + EMAC_RUNTIME_START, + EMAC_RUNTIME_STOP, +}; + +enum { + SIG_EMAC_TX_DONE, + SIG_EMAC_RX_DONE, + SIG_EMAC_TX, + SIG_EMAC_START, + SIG_EMAC_STOP, + SIG_EMAC_MAX +}; + +typedef void (*emac_phy_fun)(void); +typedef esp_err_t (*emac_tcpip_input_fun)(void *buffer, uint16_t len, void *eb); +typedef void (*emac_gpio_config_func)(void); + +struct emac_config_data { + unsigned int phy_addr; + enum emac_mode mac_mode; + struct dma_extended_desc *dma_etx; + unsigned int cur_tx; + unsigned int dirty_tx; + signed int cnt_tx; + struct dma_extended_desc *dma_erx; + unsigned int cur_rx; + unsigned int dirty_rx; + signed int cnt_rx; + unsigned int rx_need_poll; + bool phy_link_up; + enum emac_runtime_status emac_status; + uint8_t macaddr[6]; + emac_phy_fun phy_init; + emac_tcpip_input_fun emac_tcpip_input; + emac_gpio_config_func emac_gpio_config; +}; + +enum emac_post_type { + EMAC_POST_ASYNC, + EMAC_POST_SYNC, +}; + +struct emac_post_cmd { + void *cmd; + enum emac_post_type post_type; +}; + +struct emac_tx_cmd { + uint8_t *buf; + uint16_t size; + int8_t err; +}; + +struct emac_open_cmd { + int8_t err; +}; + +struct emac_close_cmd { + int8_t err; +}; +#if CONFIG_ETHERNET +#define DMA_RX_BUF_NUM CONFIG_DMA_RX_BUF_NUM +#define DMA_TX_BUF_NUM CONFIG_DMA_TX_BUF_NUM +#else +#define DMA_RX_BUF_NUM 1 +#define DMA_TX_BUF_NUM 1 +#endif +#define DMA_RX_BUF_SIZE 1600 +#define DMA_TX_BUF_SIZE 1600 + +//lwip err +#define ERR_OK 0 +#define ERR_MEM -1 +#define ERR_IF -16 + +#define EMAC_CMD_OK 0 +#define EMAC_CMD_FAIL -1 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/ethernet/emac_desc.h b/components/ethernet/emac_desc.h new file mode 100644 index 0000000000..48bdab1276 --- /dev/null +++ b/components/ethernet/emac_desc.h @@ -0,0 +1,204 @@ +// Copyright 2015-2016 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. + +#ifndef _EMAC_DESC_H_ +#define _EMAC_DESC_H_ + +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define REG_EMAC_DESC_BASE 0 +#define EMAC_DESC_TDES0_REG (REG_EMAC_DESC_BASE + 0x0000) +#define EMAC_DESC_TX_OWN (BIT(31)) +#define EMAC_DESC_TX_OWN_S 31 +#define EMAC_DESC_INT_COMPL (BIT(30)) +#define EMAC_DESC_INT_COMPL_S 30 +#define EMAC_DESC_LAST_SEGMENT (BIT(29)) +#define EMAC_DESC_LAST_SEGMENT_S 29 +#define EMAC_DESC_FIRST_SEGMENT (BIT(28)) +#define EMAC_DESC_FIRST_SEGMENT_S 28 +#define EMAC_DESC_DIS_CRC (BIT(27)) +#define EMAC_DESC_DIS_CRC_S 27 +#define EMAC_DESC_DIS_PAD (BIT(26)) +#define EMAC_DESC_DIS_PAD_S 26 +#define EMAC_DESC_TX_TS_EN (BIT(25)) +#define EMAC_DESC_TX_TS_EN_S 25 +#define EMAC_DESC_CRC_REPLACE_CTRL (BIT(24)) +#define EMAC_DESC_CRC_REPLACE_CTRL_S 24 +#define EMAC_DESC_CHECKSUM_INSERT_CTRL 0x00000003 +#define EMAC_DESC_CHECKSUM_INSERT_CTRL_S 22 +#define EMAC_DESC_TX_END_OF_RING (BIT(21)) +#define EMAC_DESC_TX_END_OF_RING_S 21 +#define EMAC_DESC_SECOND_ADDR_CHAIN (BIT(20)) +#define EMAC_DESC_SECOND_ADDR_CHAIN_S 20 +#define EMAC_DESC_VLAN_INSERT_CTRL 0x00000003 +#define EMAC_DESC_VLAN_INSERT_CTRL_S 18 +#define EMAC_DESC_TX_TS_STATUS (BIT(17)) +#define EMAC_DESC_TX_TS_STATUS_S 17 +#define EMAC_DESC_TX_IP_HEAD_ERR (BIT(16)) +#define EMAC_DESC_TX_IP_HEAD_ERR_S 16 +#define EMAC_DESC_ERR_SUMMARY (BIT(15)) +#define EMAC_DESC_ERR_SUMMARY_S 15 +#define EMAC_DESC_JABBER_TO (BIT(14)) +#define EMAC_DESC_JABBER_TO_S 14 +#define EMAC_DESC_FRAME_FLUSH (BIT(13)) +#define EMAC_DESC_FRAME_FLUSH_S 13 +#define EMAC_DESC_TX_IP_PAYLAD_ERR (BIT(12)) +#define EMAC_DESC_TX_IP_PAYLAD_ERR_S 12 +#define EMAC_DESC_LOSS_OF_CARRIER (BIT(11)) +#define EMAC_DESC_LOSS_OF_CARRIER_S 11 +#define EMAC_DESC_NO_CARRIER (BIT(10)) +#define EMAC_DESC_NO_CARRIER_S 10 +#define EMAC_DESC_LATE_COLLISION_T (BIT(9)) +#define EMAC_DESC_LATE_COLLISION_T_S 9 +#define EMAC_DESC_EXCESSIVE_COLLISION (BIT(8)) +#define EMAC_DESC_EXCESSIVE_COLLISION_S 8 +#define EMAC_DESC_VLAN_FRAME (BIT(7)) +#define EMAC_DESC_VLAN_FRAME_S 7 +#define EMAC_DESC_COLLISION_COUNT 0x0000000F +#define EMAC_DESC_COLLISION_COUNT_S 3 +#define EMAC_DESC_EXCESSIVE_DEFERRAL (BIT(2)) +#define EMAC_DESC_EXCESSIVE_DEFERRAL_S 2 +#define EMAC_DESC_UNDERFLOW_ERR (BIT(1)) +#define EMAC_DESC_UNDERFLOW_ERR_S 1 +#define EMAC_DESC_DEFFER_BIT (BIT(0)) +#define EMAC_DESC_DEFFER_BIT_S 0 + +#define EMAC_DESC_TDES1_REG (REG_EMAC_DESC_BASE + 0x0004) +#define EMAC_DESC_SA_INSERT_CRTL 0x00000007 +#define EMAC_DESC_SA_INSERT_CRTL_S 29 +#define EMAC_DESC_TX_BUFFER1_SIZE 0x00001FFF +#define EMAC_DESC_TX_BUFFER1_SIZE_S 0 + +#define EMAC_DESC_TDES2_REG (REG_EMAC_DESC_BASE + 0x0008) +#define EMAC_DESC_TX_BUFFER1_ADDR_PTR 0xFFFFFFFF +#define EMAC_DESC_TX_BUFFER1_ADDR_PTR_S 0 + +#define EMAC_DESC_TDES3_REG (REG_EMAC_DESC_BASE + 0x000C) +#define EMAC_DESC_TX_NEXT_DESC_ADDR 0xFFFFFFFF +#define EMAC_DESC_TX_NEXT_DESC_ADDR_S 0 + +#define EMAC_DESC_TDES4_REG (REG_EMAC_DESC_BASE + 0x0010) + +#define EMAC_DESC_TDES5_REG (REG_EMAC_DESC_BASE + 0x0014) + +#define EMAC_DESC_TDES6_REG (REG_EMAC_DESC_BASE + 0x0018) +#define EMAC_DESC_TX_FRAME_TS_LOW 0xFFFFFFFF +#define EMAC_DESC_TX_FRAME_TS_LOW_S 0 + +#define EMAC_DESC_TDES7_REG (REG_EMAC_DESC_BASE + 0x001C) +#define EMAC_DESC_TX_FRAME_TS_HIGH 0xFFFFFFFF +#define EMAC_DESC_TX_FRAME_TS_HIGH_S 0 + +#define EMAC_DESC_RDES0_REG (REG_EMAC_DESC_BASE + 0x0000) +#define EMAC_DESC_RX_OWN (BIT(31)) +#define EMAC_DESC_RX_OWN_S 31 +#define EMAC_DESC_DEST_ADDR_FILTER_FAIL (BIT(30)) +#define EMAC_DESC_DEST_ADDR_FILTER_FAIL_S 30 +#define EMAC_DESC_FRAME_LENGTH 0x00003FFF +#define EMAC_DESC_FRAME_LENGTH_S 16 +#define EMAC_DESC_ERROR_SUMMARY (BIT(15)) +#define EMAC_DESC_ERROR_SUMMARY_S 15 +#define EMAC_DESC_DESC_ERR (BIT(14)) +#define EMAC_DESC_DESC_ERR_S 14 +#define EMAC_DESC_SOURCE_ADDR_FILTER_FAIL (BIT(13)) +#define EMAC_DESC_SOURCE_ADDR_FILTER_FAIL_S 13 +#define EMAC_DESC_LENGTH_ERR (BIT(12)) +#define EMAC_DESC_LENGTH_ERR_S 12 +#define EMAC_DESC_OVERFLOW_ERR (BIT(11)) +#define EMAC_DESC_OVERFLOW_ERR_S 11 +#define EMAC_DESC_VLAN_TAG (BIT(10)) +#define EMAC_DESC_VLAN_TAG_S 10 +#define EMAC_DESC_FRIST_DESC (BIT(9)) +#define EMAC_DESC_FRIST_DESC_S 9 +#define EMAC_DESC_LAST_DESC (BIT(8)) +#define EMAC_DESC_LAST_DESC_S 8 +#define EMAC_DESC_TS_AV_IP_CHK_ERR (BIT(7)) +#define EMAC_DESC_TS_AV_IP_CHK_ERR_S 7 +#define EMAC_DESC_LATE_COLLISION (BIT(6)) +#define EMAC_DESC_LATE_COLLISION_S 6 +#define EMAC_DESC_FRAME_TYPE (BIT(5)) +#define EMAC_DESC_FRAME_TYPE_S 5 +#define EMAC_DESC_RX_WDT_TO (BIT(4)) +#define EMAC_DESC_RX_WDT_TO_S 4 +#define EMAC_DESC_RX_ERR (BIT(3)) +#define EMAC_DESC_RX_ERR_S 3 +#define EMAC_DESC_DRIBBLE_BIT_ERR (BIT(2)) +#define EMAC_DESC_DRIBBLE_BIT_ERR_S 2 +#define EMAC_DESC_CRC_ERR (BIT(1)) +#define EMAC_DESC_CRC_ERR_S 1 +#define EMAC_DESC_EXT_STATUS_AVAIL (BIT(0)) +#define EMAC_DESC_EXT_STATUS_AVAIL_S 0 + +#define EMAC_DESC_RDES1_REG (REG_EMAC_DESC_BASE + 0x0004) +#define EMAC_DESC_DIS_INT_ON_COMPLET (BIT(31)) +#define EMAC_DESC_DIS_INT_ON_COMPLET_S 31 +#define EMAC_DESC_RX_END_OF_RING (BIT(15)) +#define EMAC_DESC_RX_END_OF_RING_S 15 +#define EMAC_DESC_RX_SECOND_ADDR_CHAIN (BIT(14)) +#define EMAC_DESC_RX_SECOND_ADDR_CHAIN_S 14 +#define EMAC_DESC_RX_BUFFER1_SIZE 0x00001FFF +#define EMAC_DESC_RX_BUFFER1_SIZE_S 0 + +#define EMAC_DESC_RDES2_REG (REG_EMAC_DESC_BASE + 0x0008) +#define EMAC_DESC_RX_BUFFER1_ADDR_PTR 0xFFFFFFFF +#define EMAC_DESC_RX_BUFFER1_ADDR_PTR_S 0 + +#define EMAC_DESC_RDES3_REG (REG_EMAC_DESC_BASE + 0x000c) +#define EMAC_DESC_RX_NEXT_DESC_ADDR 0xFFFFFFFF +#define EMAC_DESC_RX_NEXT_DESC_ADDR_S 0 + +#define EMAC_DESC_RDES4_REG (REG_EMAC_DESC_BASE + 0x0010) +#define EMAC_DESC_VLAN_TAG_PRIOR_VALUE 0x00000007 +#define EMAC_DESC_VLAN_TAG_PRIOR_VALUE_S 18 +#define EMAC_DESC_TS_DROP (BIT(14)) +#define EMAC_DESC_TS_DROP_S 14 +#define EMAC_DESC_PTP_VERSION (BIT(13)) +#define EMAC_DESC_PTP_VERSION_S 13 +#define EMAC_DESC_PTP_FRAME_TYPE (BIT(12)) +#define EMAC_DESC_PTP_FRAME_TYPE_S 12 +#define EMAC_DESC_MESSAGE_TYPE 0x0000000F +#define EMAC_DESC_MESSAGE_TYPE_S 8 +#define EMAC_DESC_IPV6_PACK_RECEIVE (BIT(7)) +#define EMAC_DESC_IPV6_PACK_RECEIVE_S 7 +#define EMAC_DESC_IPV4_PACK_RECEIVE (BIT(6)) +#define EMAC_DESC_IPV4_PACK_RECEIVE_S 6 +#define EMAC_DESC_IP_CHECKSUM_BYPASS (BIT(5)) +#define EMAC_DESC_IP_CHECKSUM_BYPASS_S 5 +#define EMAC_DESC_RX_IP_PAYLAD_ERR (BIT(4)) +#define EMAC_DESC_RX_IP_PAYLAD_ERR_S 4 +#define EMAC_DESC_RX_IP_HEAD_ERR (BIT(3)) +#define EMAC_DESC_RX_IP_HEAD_ERR_S 3 +#define EMAC_DESC_IP_PAYLOAD_TYPE 0x00000007 +#define EMAC_DESC_IP_PAYLOAD_TYPE_S 0 + +#define EMAC_DESC_RDES5_REG (REG_EMAC_DESC_BASE + 0x0014) + +#define EMAC_DESC_RDES6_REG (REG_EMAC_DESC_BASE + 0x0018) +#define EMAC_DESC_RX_FRAME_TS_LOW 0xFFFFFFFF +#define EMAC_DESC_RX_FRAME_TS_LOW_S 0 + +#define EMAC_DESC_RDES7_REG (REG_EMAC_DESC_BASE + 0x001C) +#define EMAC_DESC_RX_FRAME_TS_HIGH 0xFFFFFFFF +#define EMAC_DESC_RX_FRAME_TS_HIGH_S 0 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/ethernet/emac_dev.c b/components/ethernet/emac_dev.c new file mode 100644 index 0000000000..a8095fecba --- /dev/null +++ b/components/ethernet/emac_dev.c @@ -0,0 +1,142 @@ +// Copyright 2015-2016 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. + +#include +#include + +#include "rom/ets_sys.h" +#include "rom/gpio.h" + +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/gpio_reg.h" +#include "soc/gpio_sig_map.h" +#include "soc/emac_reg_v2.h" +#include "soc/emac_ex_reg.h" + +#include "esp_log.h" +#include "driver/gpio.h" +#include "sdkconfig.h" + +#include "emac_common.h" + +static const char *TAG = "emac"; + +void emac_poll_tx_cmd(void) +{ + //write any to wake up dma + REG_WRITE(EMAC_DMATXPOLLDEMAND_REG, 1); +} + +void emac_poll_rx_cmd(void) +{ + //write any to wake up dma + REG_WRITE(EMAC_DMARXPOLLDEMAND_REG, 1); +} + +void emac_enable_dma_tx(void) +{ + REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_START_STOP_TRANSMISSION_COMMAND); +} + +void emac_enable_dma_rx(void) +{ + REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_START_STOP_RECEIVE); +} + +void emac_disable_dma_tx(void) +{ + REG_CLR_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_OPERATE_SECOND_FRAME); +} + +void emac_disable_dma_rx(void) +{ + REG_CLR_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_START_STOP_RECEIVE); +} + +uint32_t emac_read_tx_cur_reg(void) +{ + return REG_READ(EMAC_DMATXCURRDESC_REG); +} + +uint32_t emac_read_rx_cur_reg(void) +{ + return REG_READ(EMAC_DMARXCURRDESC_REG); +} + +uint32_t emac_read_mac_version(void) +{ + uint32_t data = 0; + data = REG_READ(EMAC_GMACVERSION_REG); + return data; +} + +void emac_reset(void) +{ + REG_SET_BIT(EMAC_DMABUSMODE_REG, EMAC_SW_RST); + + while (REG_GET_BIT(EMAC_DMABUSMODE_REG, EMAC_SW_RST) == 1) { + //nothing to do ,if stop here,maybe emac have not clk input. + ESP_LOGI(TAG, "emac reseting ...."); + } + + ESP_LOGI(TAG, "emac reset done"); +} + +void emac_enable_clk(bool enable) +{ + if (enable == true) { + REG_SET_BIT(EMAC_CLK_EN_REG, EMAC_CLK_EN); + } else { + REG_CLR_BIT(EMAC_CLK_EN_REG, EMAC_CLK_EN); + } +} + +void emac_set_clk_mii(void) +{ + //select ex clock source + REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN); + //ex clk enable + REG_SET_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL); + + //set mii mode rx/tx clk enable + REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_MII_CLK_RX_EN); + REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_MII_CLK_TX_EN); +} + +void emac_dma_init(void) +{ + REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_FORWARD_UNDERSIZED_GOOD_FRAMES); + REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_OPERATE_SECOND_FRAME); + REG_SET_FIELD(EMAC_DMABUSMODE_REG, EMAC_PROG_BURST_LEN, 4); +} + +void emac_mac_init(void) +{ + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACRX); + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACTX); + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACDUPLEX); + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACMIIGMII); + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACFESPEED); + REG_SET_BIT(EMAC_GMACFRAMEFILTER_REG, EMAC_PROMISCUOUS_MODE); +} + +void emac_set_clk_rmii(void) +{ + //select ex clock source + REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN); + //ex clk enable + REG_SET_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL); +} diff --git a/components/ethernet/emac_dev.h b/components/ethernet/emac_dev.h new file mode 100644 index 0000000000..ede15271eb --- /dev/null +++ b/components/ethernet/emac_dev.h @@ -0,0 +1,65 @@ +// Copyright 2015-2016 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. + +#ifndef _EMAC_DEV_H_ +#define _EMAC_DEV_H_ + +#include +#include "soc/emac_reg_v2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EMAC_INTR_ENABLE_BIT (EMAC_TRANSMIT_INTERRUPT_ENABLE | EMAC_RECEIVE_INTERRUPT_ENABLE | EMAC_RECEIVE_BUFFER_UNAVAILABLE_ENABLE | EMAC_NORMAL_INTERRUPT_SUMMARY_ENABLE) + +struct dma_desc { + uint32_t desc0; + uint32_t desc1; + uint32_t desc2; + uint32_t desc3; +}; + +struct dma_extended_desc { + struct dma_desc basic; + uint32_t desc4; + uint32_t desc5; + uint32_t desc6; + uint32_t desc7; +}; + +void emac_enable_clk(bool enable); +void emac_set_clk_rmii(void); +void emac_set_clk_mii(void); +void emac_reset(void); +void emac_set_gpio_pin_rmii(void); +void emac_set_gpio_pin_mii(void); +uint32_t emac_read_mac_version(void); +void emac_dma_init(void); +void emac_mac_init(void); +void emac_enable_dma_tx(void); +void emac_poll_tx_cmd(void); +uint32_t emac_read_tx_cur_reg(void); +void emac_enable_dma_rx(void); +uint32_t emac_read_rx_cur_reg(void); +void emac_poll_rx_cmd(void); +void emac_disable_dma_tx(void); +void emac_disable_dma_rx(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/ethernet/emac_main.c b/components/ethernet/emac_main.c new file mode 100644 index 0000000000..cbbab5149e --- /dev/null +++ b/components/ethernet/emac_main.c @@ -0,0 +1,768 @@ +// Copyright 2015-2016 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. + +#include +#include + +#include "rom/ets_sys.h" +#include "rom/gpio.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/gpio_reg.h" +#include "soc/dport_reg.h" +#include "soc/emac_ex_reg.h" +#include "soc/emac_reg_v2.h" +#include "soc/soc.h" + +#include "tcpip_adapter.h" +#include "sdkconfig.h" + +#include "esp_task_wdt.h" +#include "esp_event.h" +#include "esp_system.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_eth.h" + +#include "emac_common.h" +#include "emac_desc.h" + +#include "freertos/xtensa_api.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "freertos/timers.h" + +#define EMAC_EVT_QNUM 200 +#define EMAC_SIG_MAX 50 + +static struct emac_config_data emac_config; + +static uint8_t emac_dma_rx_chain_buf[32 * DMA_RX_BUF_NUM]; +static uint8_t emac_dma_tx_chain_buf[32 * DMA_TX_BUF_NUM]; +static uint8_t emac_dma_rx_buf[DMA_RX_BUF_SIZE * DMA_RX_BUF_NUM]; +static uint8_t emac_dma_tx_buf[DMA_TX_BUF_SIZE * DMA_TX_BUF_NUM]; + +static SemaphoreHandle_t emac_g_sem; +static portMUX_TYPE g_emac_mux = portMUX_INITIALIZER_UNLOCKED; +static xTaskHandle emac_task_hdl; +static xQueueHandle emac_xqueue; +static uint8_t emac_sig_cnt[EMAC_SIG_MAX] = {0}; +static TimerHandle_t emac_timer = NULL; + +static const char *TAG = "emac"; + +static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par); +esp_err_t emac_post(emac_sig_t sig, emac_par_t par); + +static void emac_macaddr_init(void) +{ + esp_efuse_read_mac(&(emac_config.macaddr[0])); + emac_config.macaddr[5] = emac_config.macaddr[5] + 3; +} + +void esp_eth_get_mac(uint8_t mac[6]) +{ + memcpy(mac, &(emac_config.macaddr[0]), 6); +} + +static void emac_setup_tx_desc(struct dma_extended_desc *tx_desc , uint32_t size) +{ + tx_desc->basic.desc0 = EMAC_DESC_TX_OWN | EMAC_DESC_INT_COMPL | EMAC_DESC_LAST_SEGMENT | EMAC_DESC_FIRST_SEGMENT | EMAC_DESC_SECOND_ADDR_CHAIN; + tx_desc->basic.desc1 = size & 0xfff; +} + +static void emac_clean_tx_desc(struct dma_extended_desc *tx_desc) +{ + tx_desc->basic.desc0 = 0; + tx_desc->basic.desc1 = 0; +} + +static void emac_clean_rx_desc(struct dma_extended_desc *rx_desc) +{ + rx_desc->basic.desc0 = EMAC_DESC_RX_OWN; + rx_desc->basic.desc1 = EMAC_DESC_RX_SECOND_ADDR_CHAIN | DMA_RX_BUF_SIZE; +} + +static void emac_set_tx_base_reg(void) +{ + REG_WRITE(EMAC_DMATXBASEADDR_REG, (uint32_t)(emac_config.dma_etx)); +} + +static void emac_set_rx_base_reg(void) +{ + REG_WRITE(EMAC_DMARXBASEADDR_REG, (uint32_t)(emac_config.dma_erx)); +} + +static void emac_reset_dma_chain(void) +{ + emac_config.cnt_tx = 0; + emac_config.cur_tx = 0; + emac_config.dirty_tx = 0; + + emac_config.cnt_rx = 0; + emac_config.cur_rx = 0; + emac_config.dirty_rx = 0; +} + +static void emac_init_dma_chain(void) +{ + int i; + uint32_t dma_phy; + struct dma_extended_desc *p = NULL; + + //init tx chain + emac_config.dma_etx = (struct dma_extended_desc *)(&emac_dma_tx_chain_buf[0]); + emac_config.cnt_tx = 0; + emac_config.cur_tx = 0; + emac_config.dirty_tx = 0; + + dma_phy = (uint32_t)(emac_config.dma_etx); + p = emac_config.dma_etx; + + for (i = 0; i < (DMA_TX_BUF_NUM - 1); i++ ) { + dma_phy += sizeof(struct dma_extended_desc); + emac_clean_tx_desc(p); + p->basic.desc3 = dma_phy; + p->basic.desc2 = (uint32_t)(&emac_dma_tx_buf[0]) + (i * DMA_TX_BUF_SIZE); + p++; + } + p->basic.desc3 = (uint32_t)(emac_config.dma_etx); + p->basic.desc2 = (uint32_t)(&emac_dma_tx_buf[0]) + (i * DMA_TX_BUF_SIZE); + + //init desc0 desc1 + emac_clean_tx_desc(p); + + //init rx chain + emac_config.dma_erx = (struct dma_extended_desc *)(&emac_dma_rx_chain_buf[0]); + emac_config.cnt_rx = 0; + emac_config.cur_rx = 0; + emac_config.dirty_rx = 0; + + dma_phy = (uint32_t)(emac_config.dma_erx); + p = emac_config.dma_erx; + + for (i = 0; i < (DMA_TX_BUF_NUM - 1); i++ ) { + dma_phy += sizeof(struct dma_extended_desc); + emac_clean_rx_desc(p); + p->basic.desc3 = dma_phy; + p->basic.desc2 = (uint32_t)(&emac_dma_rx_buf[0]) + (i * DMA_RX_BUF_SIZE); + p++; + } + p->basic.desc3 = (uint32_t)(emac_config.dma_erx); + p->basic.desc2 = (uint32_t)(&emac_dma_rx_buf[0]) + (i * DMA_RX_BUF_SIZE); + + //init desc0 desc1 + emac_clean_rx_desc(p); +} + +void esp_eth_smi_write(uint32_t reg_num, uint16_t value) +{ + uint32_t phy_num = emac_config.phy_addr; + + while (REG_GET_BIT(EMAC_GMACGMIIADDR_REG, EMAC_GMIIBUSY) == 1 ) { + } + + REG_WRITE(EMAC_GMACGMIIDATA_REG, value); + REG_WRITE(EMAC_GMACGMIIADDR_REG, 0x3 | ((reg_num & 0x1f) << 6) | ((phy_num & 0x1f) << 11) | ((0x3) << 2)); + + while (REG_GET_BIT(EMAC_GMACGMIIADDR_REG, EMAC_GMIIBUSY) == 1 ) { + } +} + +uint16_t esp_eth_smi_read(uint32_t reg_num) +{ + uint32_t phy_num = emac_config.phy_addr; + uint16_t value = 0; + + while (REG_GET_BIT(EMAC_GMACGMIIADDR_REG, EMAC_GMIIBUSY) == 1 ) { + } + + REG_WRITE(EMAC_GMACGMIIADDR_REG, 0x1 | ((reg_num & 0x1f) << 6) | ((phy_num & 0x1f) << 11) | (0x3 << 2)); + while (REG_GET_BIT(EMAC_GMACGMIIADDR_REG, EMAC_GMIIBUSY) == 1 ) { + } + value = (REG_READ(EMAC_GMACGMIIDATA_REG) & 0xffff); + + return value; +} + +static void emac_set_user_config_data(eth_config_t *config ) +{ + emac_config.phy_addr = config->phy_addr; + emac_config.mac_mode = config->mac_mode; + emac_config.phy_init = config->phy_init; + emac_config.emac_tcpip_input = config->tcpip_input; + emac_config.emac_gpio_config = config->gpio_config; +} + +static esp_err_t emac_verify_args(void) +{ + esp_err_t ret = ESP_OK; + + if (emac_config.phy_addr > 31) { + ESP_LOGE(TAG, "phy addr err"); + ret = ESP_FAIL; + } + + if (emac_config.mac_mode != EMAC_MODE_RMII) { + ESP_LOGE(TAG, "mac mode err,now only support RMII"); + ret = ESP_FAIL; + } + + if (emac_config.phy_init == NULL) { + ESP_LOGE(TAG, "phy_init func is null"); + ret = ESP_FAIL; + } + + if (emac_config.emac_tcpip_input == NULL) { + ESP_LOGE(TAG, "tcpip_input func is null"); + ret = ESP_FAIL; + } + + if (emac_config.emac_gpio_config == NULL) { + ESP_LOGE(TAG, "gpio config func is null"); + ret = ESP_FAIL; + } + + return ret; +} + +//TODO for mac filter +void emac_set_mac_addr(void) +{ +} + +//TODO +void emac_check_mac_addr(void) +{ +} + +static void emac_process_tx(void) +{ + uint32_t cur_tx_desc = emac_read_tx_cur_reg(); + + while (((uint32_t) & (emac_config.dma_etx[emac_config.dirty_tx].basic.desc0) != cur_tx_desc)) { + emac_clean_tx_desc(&(emac_config.dma_etx[emac_config.dirty_tx])); + emac_config.dirty_tx = (emac_config.dirty_tx + 1) % DMA_TX_BUF_NUM; + emac_config.cnt_tx --; + + if (emac_config.cnt_tx < 0) { + ESP_LOGE(TAG, "emac tx chain err"); + } + } +} + +static void emac_process_rx(void) +{ + uint32_t cur_rx_desc = emac_read_rx_cur_reg(); + + while (((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) != cur_rx_desc)) { + //copy data to lwip + emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2), + (((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL); + + emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.dirty_rx])); + emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM; + if (emac_config.rx_need_poll != 0) { + emac_poll_rx_cmd(); + emac_config.rx_need_poll = 0; + } + //if open this ,one intr can do many intrs ? + //cur_rx_desc = emac_read_rx_cur_reg(); + } +} + +//TODO other events need to do something +static void IRAM_ATTR emac_process_intr(void *arg) +{ + uint32_t event; + event = REG_READ(EMAC_DMASTATUS_REG); + + //clr intrs + REG_WRITE(EMAC_DMASTATUS_REG, event); + + if (event & EMAC_RECV_BUF_UNAVAIL) { + emac_config.rx_need_poll = 1; + } else if (event & EMAC_TRANS_INT) { + emac_post(SIG_EMAC_TX_DONE, 0); + } else if (event & EMAC_RECV_INT) { + emac_post(SIG_EMAC_RX_DONE, 0); + } else { + //other events + } +} + +static void emac_enable_intr() +{ + //init emac intr + REG_SET_FIELD(DPORT_PRO_EMAC_INT_MAP_REG, DPORT_PRO_EMAC_INT_MAP, ETS_EMAC_INUM); + xt_set_interrupt_handler(ETS_EMAC_INUM, emac_process_intr, NULL); + xt_ints_on(1 << ETS_EMAC_INUM); + + REG_WRITE(EMAC_DMAINTERRUPT_EN_REG, EMAC_INTR_ENABLE_BIT); +} + +static void emac_disable_intr() +{ + xt_ints_off(1 << ETS_EMAC_INUM); + REG_WRITE(EMAC_DMAINTERRUPT_EN_REG, 0); +} + +static bool emac_check_phy_link_status(void) +{ + return ((esp_eth_smi_read(1) & 0x4) == 0x4 ); +} + +static void emac_process_link_updown(bool link_status) +{ + system_event_t evt; + + emac_config.phy_link_up = link_status; + + if (link_status == true) { + ESP_LOGI(TAG, "eth link_up!!!"); + emac_enable_dma_tx(); + emac_enable_dma_rx(); + ets_delay_us(200000); + evt.event_id = SYSTEM_EVENT_ETH_CONNECTED; + } else { + ESP_LOGI(TAG, "eth link_down!!!"); + emac_disable_dma_tx(); + emac_disable_dma_rx(); + evt.event_id = SYSTEM_EVENT_ETH_DISCONNECTED; + } + + esp_event_send(&evt); +} + +static void emac_hw_init(void) +{ + //init chain + emac_init_dma_chain(); + + //get hw features TODO + + //ipc TODO +} + +static esp_err_t emac_xmit(void *param) +{ + struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param; + struct emac_tx_cmd *cmd = (struct emac_tx_cmd *)(post_cmd->cmd); + esp_err_t ret = ESP_OK; + + void *buf = cmd->buf; + uint16_t size = cmd->size; + + if (emac_config.emac_status != EMAC_RUNTIME_START || emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) { + ESP_LOGI(TAG, "tx netif close"); + cmd->err = ERR_IF; + ret = ESP_FAIL; + goto _exit; + } + + if (emac_config.cnt_tx == DMA_TX_BUF_NUM) { + ESP_LOGI(TAG, "tx buf full"); + cmd->err = ERR_MEM; + ret = ESP_FAIL; + goto _exit; + } + + memcpy((uint8_t *)(emac_config.dma_etx[emac_config.cur_tx].basic.desc2), (uint8_t *)buf, size); + + emac_setup_tx_desc(&(emac_config.dma_etx[emac_config.cur_tx]), size); + + emac_config.cnt_tx ++; + emac_config.cur_tx = (emac_config.cur_tx + 1) % DMA_TX_BUF_NUM ; + + emac_poll_tx_cmd(); + +_exit: + + if (post_cmd->post_type == EMAC_POST_SYNC) { + xSemaphoreGive(emac_g_sem); + } + + return ret; +} + +static void emac_init_default_data(void) +{ + emac_config.rx_need_poll = 0; +} + +void emac_link_check_func(void *pv_parameters) +{ + if (emac_config.emac_status != EMAC_RUNTIME_START || + emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) { + return; + } + + if (emac_check_phy_link_status() == true ) { + if (emac_config.phy_link_up == false) { + emac_process_link_updown(true); + } + } else { + if (emac_config.phy_link_up == true) { + emac_process_link_updown(false); + } + } +} + +static bool emac_link_check_timer_init(void) +{ + emac_timer = xTimerCreate("emac_timer", (1000 / portTICK_RATE_MS), + pdTRUE, (void *)rand(), emac_link_check_func); + if (emac_timer == NULL) { + return false; + } else { + return true; + } +} + +static bool emac_link_check_timer_start(void) +{ + if (xTimerStart(emac_timer, portMAX_DELAY) != pdPASS) { + return false; + } else { + return true; + } +} + +static bool emac_link_check_timer_stop(void) +{ + if (xTimerStop(emac_timer, portMAX_DELAY) != pdPASS) { + return false; + } else { + return true; + } +} + +static bool emac_link_check_timer_delete(void) +{ + xTimerDelete(emac_timer, portMAX_DELAY); + emac_timer = NULL; + return true; +} + +static void emac_start(void *param) +{ + struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param; + struct emac_open_cmd *cmd = (struct emac_open_cmd *)(post_cmd->cmd); + + ESP_LOGI(TAG , "emac start !!!\n"); + cmd->err = EMAC_CMD_OK; + emac_enable_clk(true); + + emac_macaddr_init(); + + emac_check_mac_addr(); + + emac_set_mac_addr(); + + emac_set_tx_base_reg(); + emac_set_rx_base_reg(); + emac_mac_init(); + + emac_config.phy_init(); + + //for test + //emac_wait_linkup(); + + //mmc not support + + //ptp TODO + + //enable emac intr + emac_enable_intr(); + + emac_config.emac_status = EMAC_RUNTIME_START; + + system_event_t evt; + evt.event_id = SYSTEM_EVENT_ETH_START; + esp_event_send(&evt); + + //set a timer to check link up status + if (emac_link_check_timer_init() == true) { + if (emac_link_check_timer_start() != true) { + cmd->err = EMAC_CMD_FAIL; + emac_link_check_timer_delete(); + } + } else { + cmd->err = EMAC_CMD_FAIL; + } + + if (post_cmd->post_type == EMAC_POST_SYNC) { + xSemaphoreGive(emac_g_sem); + } + + ESP_LOGI(TAG, "emac start success !!!"); +} + +esp_err_t esp_eth_enable(void) +{ + struct emac_post_cmd post_cmd; + struct emac_open_cmd open_cmd; + + post_cmd.cmd = (void *)(&open_cmd); + open_cmd.err = EMAC_CMD_OK; + + if (emac_config.emac_status == EMAC_RUNTIME_START) { + open_cmd.err = EMAC_CMD_OK; + return open_cmd.err; + } + + if (emac_config.emac_status != EMAC_RUNTIME_NOT_INIT) { + if (emac_ioctl(SIG_EMAC_START, (emac_par_t)(&post_cmd)) != 0) { + open_cmd.err = EMAC_CMD_FAIL; + } + } else { + open_cmd.err = EMAC_CMD_FAIL; + } + return open_cmd.err; +} + +static void emac_stop(void *param) +{ + struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param; + ESP_LOGI(TAG, "emac stop"); + + emac_link_check_timer_stop(); + emac_link_check_timer_delete(); + + emac_process_link_updown(false); + + emac_disable_intr(); + emac_reset_dma_chain(); + emac_reset(); + emac_enable_clk(false); + + emac_config.emac_status = EMAC_RUNTIME_STOP; + system_event_t evt; + evt.event_id = SYSTEM_EVENT_ETH_STOP; + esp_event_send(&evt); + + if (post_cmd->post_type == EMAC_POST_SYNC) { + xSemaphoreGive(emac_g_sem); + } + + ESP_LOGI(TAG, "emac stop success !!!"); +} + +esp_err_t esp_eth_disable(void) +{ + struct emac_post_cmd post_cmd; + struct emac_close_cmd close_cmd; + + post_cmd.cmd = (void *)(&close_cmd); + close_cmd.err = EMAC_CMD_OK; + + if (emac_config.emac_status == EMAC_RUNTIME_STOP) { + close_cmd.err = EMAC_CMD_OK; + return close_cmd.err; + } + + if (emac_config.emac_status != EMAC_RUNTIME_NOT_INIT) { + if (emac_ioctl(SIG_EMAC_STOP, (emac_par_t)(&post_cmd)) != 0) { + close_cmd.err = EMAC_CMD_FAIL; + } + } else { + close_cmd.err = EMAC_CMD_FAIL; + } + return close_cmd.err; +} + +static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par) +{ + esp_err_t ret = ESP_OK; + struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)par; + xTaskHandle task_hdl = xTaskGetCurrentTaskHandle(); + + if (emac_task_hdl != task_hdl) { + post_cmd->post_type = EMAC_POST_SYNC; + if (emac_post(sig, par) != ESP_OK) { + ret = ESP_FAIL; + return ret; + }; + + if (xSemaphoreTake(emac_g_sem, portMAX_DELAY) == pdTRUE) { + return ret; + } + } else { + post_cmd->post_type = EMAC_POST_ASYNC; + switch (sig) { + case SIG_EMAC_RX_DONE: + emac_process_rx(); + break; + case SIG_EMAC_TX_DONE: + emac_process_tx(); + break; + case SIG_EMAC_TX: + emac_xmit((void *)par); + break; + case SIG_EMAC_START: + emac_start((void *)par); + break; + case SIG_EMAC_STOP: + emac_stop((void *)par); + break; + default: + ESP_LOGE(TAG, "unexpect sig %d", sig); + break; + } + } + + return ret; +} + +esp_err_t esp_eth_tx(uint8_t *buf, uint16_t size) +{ + struct emac_post_cmd post_cmd; + struct emac_tx_cmd tx_cmd; + + post_cmd.cmd = (void *)(&tx_cmd); + + if (emac_check_phy_link_status() == false) { + emac_process_link_updown(false); + tx_cmd.err = ERR_IF; + } else { + tx_cmd.buf = buf; + tx_cmd.size = size; + tx_cmd.err = ERR_OK; + + if (emac_ioctl(SIG_EMAC_TX, (emac_par_t)(&post_cmd)) != 0) { + tx_cmd.err = ERR_MEM; + } + } + + return tx_cmd.err; +} + +void emac_task(void *pv) +{ + emac_event_t e; + + for (;;) { + if (xQueueReceive(emac_xqueue, &e, (portTickType)portMAX_DELAY) == pdTRUE) { + portENTER_CRITICAL(&g_emac_mux); + emac_sig_cnt[e.sig]--; + portEXIT_CRITICAL(&g_emac_mux); + switch (e.sig) { + case SIG_EMAC_RX_DONE: + emac_process_rx(); + break; + case SIG_EMAC_TX_DONE: + emac_process_tx(); + break; + case SIG_EMAC_TX: + emac_xmit((void *)e.par); + break; + case SIG_EMAC_START: + emac_start((void *)e.par); + break; + case SIG_EMAC_STOP: + emac_stop((void *)e.par); + break; + default: + ESP_LOGE(TAG, "unexpect sig %d", e.sig); + break; + } + } + } +} + +esp_err_t IRAM_ATTR emac_post(emac_sig_t sig, emac_par_t par) +{ + portENTER_CRITICAL(&g_emac_mux); + + if (emac_sig_cnt[sig] && sig != SIG_EMAC_TX) { + portEXIT_CRITICAL(&g_emac_mux); + return ESP_OK; + } else { + emac_sig_cnt[sig]++; + portEXIT_CRITICAL(&g_emac_mux); + emac_event_t evt; + evt.sig = sig; + evt.par = par; + if (sig <= SIG_EMAC_RX_DONE) { + portBASE_TYPE tmp; + + if (xQueueSendFromISR(emac_xqueue, &evt, &tmp) != pdPASS) { + return ESP_FAIL; + } + } else { + if (xQueueSend(emac_xqueue, &evt, 10 / portTICK_RATE_MS) != pdTRUE) { + return ESP_FAIL; + } + } + } + + return ESP_OK; +} + +esp_err_t esp_eth_init(eth_config_t *config) +{ + esp_err_t ret = ESP_OK; +#if !CONFIG_ETHERNET + ESP_LOGI(TAG, "eth driver init fail,please make menuconfig and enable ethernet ."); + ret = ESP_FAIL; + goto _exit; +#endif + + emac_init_default_data(); + + if (config != NULL ) { + emac_set_user_config_data(config); + } + + ret = emac_verify_args(); + + if (ret != ESP_OK) { + goto _exit; + } + + //before set emac reg must enable clk + emac_enable_clk(true); + REG_SET_FIELD(EMAC_EX_PHYINF_CONF_REG, EMAC_EX_PHY_INTF_SEL, EMAC_EX_PHY_INTF_RMII); + + emac_dma_init(); + if (emac_config.mac_mode == EMAC_MODE_RMII) { + emac_set_clk_rmii(); + } else { + emac_set_clk_mii(); + } + + emac_config.emac_gpio_config(); + + ESP_LOGI(TAG, "mac version %04xa", emac_read_mac_version()); + emac_hw_init(); + + //watchdog TODO + + //init task for emac + emac_g_sem = xSemaphoreCreateBinary(); + emac_xqueue = xQueueCreate(EMAC_EVT_QNUM, sizeof(emac_event_t)); + xTaskCreate(emac_task, "emacT", 2048 * 4, NULL, (19), &emac_task_hdl); + + emac_reset(); + emac_enable_clk(false); + + emac_config.emac_status = EMAC_RUNTIME_INIT; + +_exit: + return ret; +} + diff --git a/components/ethernet/include/esp_eth.h b/components/ethernet/include/esp_eth.h new file mode 100644 index 0000000000..b97289dd2b --- /dev/null +++ b/components/ethernet/include/esp_eth.h @@ -0,0 +1,167 @@ +// Copyright 2015-2016 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. + +#ifndef __ESP_ETH_H__ +#define __ESP_ETH_H__ + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*eth_phy_fun)(void); +typedef esp_err_t (*eth_tcpip_input_fun)(void *buffer, uint16_t len, void *eb); +typedef void (*eth_gpio_config_func)(void); + +typedef enum { + ETH_MODE_RMII = 0, + ETH_MDOE_MII, +} eth_mode_t; + +typedef enum { + PHY0 = 0, + PHY1, + PHY2, + PHY3, + PHY4, + PHY5, + PHY6, + PHY7, + PHY8, + PHY9, + PHY10, + PHY11, + PHY12, + PHY13, + PHY14, + PHY15, + PHY16, + PHY17, + PHY18, + PHY19, + PHY20, + PHY21, + PHY22, + PHY23, + PHY24, + PHY25, + PHY26, + PHY27, + PHY28, + PHY29, + PHY30, + PHY31, +} eth_phy_base_t; + +/** + * @brief ethernet configuration + * + */ +typedef struct { + eth_phy_base_t phy_addr; /*!< phy base addr (0~31) */ + eth_mode_t mac_mode; /*!< mac mode only support RMII now */ + eth_tcpip_input_fun tcpip_input; /*!< tcpip input func */ + eth_phy_fun phy_init; /*!< phy init func */ + eth_gpio_config_func gpio_config; /*!< gpio config func */ +} eth_config_t; + +/** + * @brief Init ethernet mac + * + * @note config can not be NULL,and phy chip must be suitable to phy init func. + * + * @param[in] config mac init data. + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_eth_init(eth_config_t *config); + +/** + * @brief Send packet from tcp/ip to mac + * + * @note buf can not be NULL,size must be less than 1580 + * + * @param[in] buf: start address of packet data. + * + * @param[in] size: size (byte) of packet data. + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_eth_tx(uint8_t *buf, uint16_t size); + +/** + * @brief Enable ethernet interface + * + * @note Shout be called after esp_eth_init + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_eth_enable(void); + +/** + * @brief Disable ethernet interface + * + * @note Shout be called after esp_eth_init + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t esp_eth_disable(void); + +/** + * @brief Get mac addr + * + * @note mac addr must be a valid unicast address + * + * @param[out] mac: start address of mac address. + */ +void esp_eth_get_mac(uint8_t mac[6]); + +/** + * @brief Read phy reg with smi interface. + * + * @note phy base addr must be right. + * + * @param[in] reg_num: phy reg num. + * + * @param[in] value: value which write to phy reg. + */ +void esp_eth_smi_write(uint32_t reg_num, uint16_t value); + +/** + * @brief Write phy reg with smi interface. + * + * @note phy base addr must be right. + * + * @param[in] reg_num: phy reg num. + * + * @return value what read from phy reg + */ +uint16_t esp_eth_smi_read(uint32_t reg_num); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/lwip/apps/dhcpserver.c b/components/lwip/apps/dhcpserver.c index 22443e8cde..fcb27f0b05 100644 --- a/components/lwip/apps/dhcpserver.c +++ b/components/lwip/apps/dhcpserver.c @@ -266,7 +266,7 @@ static u8_t *add_offer_options(u8_t *optptr) //bzero(&if_ip, sizeof(struct ip_info)); memset(&if_ip , 0x00, sizeof(tcpip_adapter_ip_info_t)); - tcpip_adapter_get_ip_info(WIFI_IF_AP, &if_ip); + tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &if_ip); *optptr++ = DHCP_OPTION_ROUTER; *optptr++ = 4; diff --git a/components/lwip/core/ipv4/dhcp.c b/components/lwip/core/ipv4/dhcp.c index 33d13fb326..887af91fe3 100755 --- a/components/lwip/core/ipv4/dhcp.c +++ b/components/lwip/core/ipv4/dhcp.c @@ -713,7 +713,11 @@ void dhcp_cleanup(struct netif *netif) * @param netif the netif from which to remove the struct dhcp * @param cb callback for dhcp */ +#ifdef ESP_LWIP +void dhcp_set_cb(struct netif *netif, void (*cb)(struct netif*)) +#else void dhcp_set_cb(struct netif *netif, void (*cb)(void)) +#endif { LWIP_ASSERT("netif != NULL", netif != NULL); @@ -1141,7 +1145,11 @@ dhcp_bind(struct netif *netif) /* Espressif add start. */ if (dhcp->cb != NULL) { +#ifdef ESP_LWIP + dhcp->cb(netif); +#else dhcp->cb(); +#endif } /* Espressif add end. */ } diff --git a/components/lwip/include/lwip/lwip/dhcp.h b/components/lwip/include/lwip/lwip/dhcp.h index 76ce1543ff..c3a057ac0f 100755 --- a/components/lwip/include/lwip/lwip/dhcp.h +++ b/components/lwip/include/lwip/lwip/dhcp.h @@ -96,7 +96,11 @@ struct dhcp #endif /* LWIP_DHCP_BOOTPFILE */ /* Espressif add start. */ +#ifdef ESP_LWIP + void (*cb)(struct netif*); /* callback for dhcp, add a parameter to show dhcp status if needed */ +#else void (*cb)(void); /* callback for dhcp, add a parameter to show dhcp status if needed */ +#endif /* Espressif add end. */ }; @@ -146,7 +150,11 @@ void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); void dhcp_cleanup(struct netif *netif); /* Espressif add start. */ /** set callback for DHCP */ +#ifdef ESP_LWIP +void dhcp_set_cb(struct netif *netif, void (*cb)(struct netif*)); +#else void dhcp_set_cb(struct netif *netif, void (*cb)(void)); +#endif /* Espressif add end. */ /** start DHCP configuration */ err_t dhcp_start(struct netif *netif); diff --git a/components/lwip/include/lwip/port/netif/ethernetif.h b/components/lwip/include/lwip/port/netif/ethernetif.h new file mode 100755 index 0000000000..134e8eb5fe --- /dev/null +++ b/components/lwip/include/lwip/port/netif/ethernetif.h @@ -0,0 +1,35 @@ +// Copyright 2015-2016 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. + + +#ifndef _ETH_LWIP_IF_H_ +#define _ETH_LWIP_IF_H_ + +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +err_t ethernetif_init(struct netif *netif); + +void ethernetif_input(struct netif *netif, void *buffer, u16_t len); + +void netif_reg_addr_change_cb(void* cb); + +#ifdef __cplusplus +} +#endif + +#endif /* _ETH_LWIP_IF_H_ */ diff --git a/components/lwip/include/lwip/port/netif/wlanif.h b/components/lwip/include/lwip/port/netif/wlanif.h index c6f7831b3d..5a93640f19 100755 --- a/components/lwip/include/lwip/port/netif/wlanif.h +++ b/components/lwip/include/lwip/port/netif/wlanif.h @@ -1,7 +1,17 @@ -/* - * Copyright (c) 2010-2011 Espressif System - * -*/ +// Copyright 2015-2016 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. + #ifndef _WLAN_LWIP_IF_H_ #define _WLAN_LWIP_IF_H_ diff --git a/components/lwip/port/netif/ethernetif.c b/components/lwip/port/netif/ethernetif.c new file mode 100755 index 0000000000..c6f08ec832 --- /dev/null +++ b/components/lwip/port/netif/ethernetif.c @@ -0,0 +1,235 @@ +/** + * @file + * Ethernet Interface Skeleton + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/ethip6.h" +#include "netif/etharp.h" +#include +#include + +#include "esp_eth.h" +#include "tcpip_adapter.h" + +/* Define those to better describe your network interface. */ +#define IFNAME0 'e' +#define IFNAME1 'n' + +static char hostname[16]; +#if ESP_PERF +uint32_t g_rx_alloc_pbuf_fail_cnt = 0; +#endif + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void +ethernet_low_level_init(struct netif *netif) +{ + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set MAC hardware address */ + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + +#if ESP_LWIP +#if LWIP_IGMP + + netif->flags |= NETIF_FLAG_IGMP; +#endif +#endif + /* Do whatever else is needed to initialize interface. */ +} + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ +static err_t +ethernet_low_level_output(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q; + esp_interface_t eth_if = tcpip_adapter_get_esp_if(netif); + + if (eth_if != ESP_IF_ETH) { + printf("eth_if=%d netif=%p pbuf=%p len=%d\n", eth_if, netif, p, p->len); + return ERR_IF; + } + +#if ESP_LWIP + q = p; + u16_t pbuf_x_len = 0; + pbuf_x_len = q->len; + if(q->next !=NULL) + { + //char cnt = 0; + struct pbuf *tmp = q->next; + while(tmp != NULL) + { + memcpy( (u8_t *)( (u8_t *)(q->payload) + pbuf_x_len), (u8_t *)tmp->payload , tmp->len ); + pbuf_x_len += tmp->len; + //cnt++; + tmp = tmp->next; + } + } + + //printf("netif=%p pbuf=%p len=%d\n", netif, p, p->len); + return esp_eth_tx(q->payload, pbuf_x_len); +#else + for(q = p; q != NULL; q = q->next) { + return esp_emac_tx(q->payload, q->len); + } + return ERR_OK; +#endif +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +void +ethernetif_input(struct netif *netif, void *buffer, uint16_t len) +{ + struct pbuf *p; + + if(buffer== NULL || netif == NULL) + goto _exit; + + p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); + if (p == NULL) { + //g_rx_alloc_pbuf_fail_cnt++; + return; + } + memcpy(p->payload, buffer, len); + + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + } + +_exit: +; +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t +ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + +#if ESP_LWIP + sprintf(hostname, "ESP_%02X%02X%02X", netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5]); + netif->hostname = hostname; + +#else + sprintf(hostname, "ESP_%02X%02X%02X", netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5]); + netif->hostname = hostname; +#endif + +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif /* LWIP_IPV6 */ + netif->linkoutput = ethernet_low_level_output; + + /* initialize the hardware */ + ethernet_low_level_init(netif); + + return ERR_OK; +} diff --git a/components/lwip/port/netif/wlanif.c b/components/lwip/port/netif/wlanif.c index 7a5464b2da..efaa76a73f 100755 --- a/components/lwip/port/netif/wlanif.c +++ b/components/lwip/port/netif/wlanif.c @@ -118,11 +118,11 @@ low_level_init(struct netif *netif) static err_t low_level_output(struct netif *netif, struct pbuf *p) { - wifi_interface_t wifi_if = tcpip_adapter_get_wifi_if(netif); + wifi_interface_t wifi_if = tcpip_adapter_get_esp_if(netif); struct pbuf *q = p; err_t ret; - if (wifi_if >= WIFI_IF_MAX) { + if (wifi_if >= ESP_IF_MAX) { return ERR_IF; } diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index b0de3ddcbc..861f7ccb8d 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -98,6 +98,7 @@ typedef struct { typedef enum { TCPIP_ADAPTER_IF_STA = 0, /**< ESP32 station interface */ TCPIP_ADAPTER_IF_AP, /**< ESP32 soft-AP interface */ + TCPIP_ADAPTER_IF_ETH, /**< ESP32 ethernet interface */ TCPIP_ADAPTER_IF_MAX } tcpip_adapter_if_t; @@ -354,6 +355,10 @@ esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if); */ esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if); + + +esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb); + /** * @brief Get data from station interface * @@ -387,11 +392,12 @@ esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb); * * @param[in] void *dev: adapter interface * - * @return WIFI_IF_STA - * WIFI_IF_AP - * WIFI_IF_MAX + * @return ESP_IF_WIFI_STA + * ESP_IF_WIFI_AP + ESP_IF_ETH + * ESP_IF_MAX */ -wifi_interface_t tcpip_adapter_get_wifi_if(void *dev); +esp_interface_t tcpip_adapter_get_esp_if(void *dev); /** * @brief Get the station information list diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 4230cc39f0..222e8017eb 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -26,6 +26,7 @@ #include "lwip/ip6_addr.h" #include "lwip/nd6.h" #include "netif/wlanif.h" +#include "netif/ethernetif.h" #include "apps/dhcpserver.h" @@ -36,9 +37,10 @@ static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX]; static tcpip_adapter_ip6_info_t esp_ip6[TCPIP_ADAPTER_IF_MAX]; static tcpip_adapter_dhcp_status_t dhcps_status = TCPIP_ADAPTER_DHCP_INIT; -static tcpip_adapter_dhcp_status_t dhcpc_status = TCPIP_ADAPTER_DHCP_INIT; +static tcpip_adapter_dhcp_status_t dhcpc_status[TCPIP_ADAPTER_IF_MAX] = {TCPIP_ADAPTER_DHCP_INIT}; #define TCPIP_ADAPTER_DEBUG(...) +//#define TCPIP_ADAPTER_DEBUG printf void tcpip_adapter_init(void) { @@ -67,7 +69,11 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_a return ESP_ERR_NO_MEM; } memcpy(esp_netif[tcpip_if]->hwaddr, mac, NETIF_MAX_HWADDR_LEN); - netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, NULL, wlanif_init, tcpip_input); + if (tcpip_if == TCPIP_ADAPTER_IF_AP || tcpip_if == TCPIP_ADAPTER_IF_STA) { + netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, NULL, wlanif_init, tcpip_input); + } else if (tcpip_if == TCPIP_ADAPTER_IF_ETH) { + netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, NULL, ethernetif_init, tcpip_input); + } } if (tcpip_if == TCPIP_ADAPTER_IF_AP) { @@ -77,7 +83,7 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_a dhcps_start(esp_netif[tcpip_if], ip_info->ip); printf("dhcp server start:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")\n", - IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw)); + IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw)); dhcps_status = TCPIP_ADAPTER_DHCP_STARTED; } @@ -88,6 +94,8 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_a netif_set_default(esp_netif[TCPIP_ADAPTER_IF_AP]); } else if (esp_netif[TCPIP_ADAPTER_IF_STA]) { netif_set_default(esp_netif[TCPIP_ADAPTER_IF_STA]); + } else if (esp_netif[TCPIP_ADAPTER_IF_ETH] ) { + netif_set_default(esp_netif[TCPIP_ADAPTER_IF_ETH]); } return ESP_OK; @@ -105,15 +113,15 @@ esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if) if (tcpip_if == TCPIP_ADAPTER_IF_AP) { dhcps_stop(esp_netif[tcpip_if]); // TODO: dhcps checks status by its self - if (TCPIP_ADAPTER_DHCP_STOPPED != dhcps_status){ + if (TCPIP_ADAPTER_DHCP_STOPPED != dhcps_status) { dhcps_status = TCPIP_ADAPTER_DHCP_INIT; } - } else if (tcpip_if == TCPIP_ADAPTER_IF_STA) { + } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) { dhcp_release(esp_netif[tcpip_if]); dhcp_stop(esp_netif[tcpip_if]); dhcp_cleanup(esp_netif[tcpip_if]); - dhcpc_status = TCPIP_ADAPTER_DHCP_INIT; + dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; ip4_addr_set_zero(&esp_ip[tcpip_if].ip); ip4_addr_set_zero(&esp_ip[tcpip_if].gw); @@ -135,8 +143,8 @@ esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if) esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if) { - if (tcpip_if == TCPIP_ADAPTER_IF_STA) { - if (esp_netif[tcpip_if] == NULL){ + if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) { + if (esp_netif[tcpip_if] == NULL) { return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } @@ -150,15 +158,15 @@ esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if) esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if) { - if (tcpip_if == TCPIP_ADAPTER_IF_STA) { + if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) { if (esp_netif[tcpip_if] == NULL) { return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } - if (dhcpc_status == TCPIP_ADAPTER_DHCP_STARTED) { + if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) { dhcp_stop(esp_netif[tcpip_if]); - dhcpc_status = TCPIP_ADAPTER_DHCP_INIT; + dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; ip4_addr_set_zero(&esp_ip[tcpip_if].ip); ip4_addr_set_zero(&esp_ip[tcpip_if].gw); @@ -215,7 +223,7 @@ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i if (status != TCPIP_ADAPTER_DHCP_STOPPED) { return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED; } - } else if (tcpip_if == TCPIP_ADAPTER_IF_STA) { + } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) { tcpip_adapter_dhcpc_get_status(tcpip_if, &status); if (status != TCPIP_ADAPTER_DHCP_STOPPED) { @@ -247,8 +255,8 @@ static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex) if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) { ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_STA]; - } else if(p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) { - ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_AP]; + } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) { + ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_AP]; } else { return; } @@ -272,7 +280,7 @@ esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if) } p_netif = esp_netif[tcpip_if]; - if(p_netif != NULL && netif_is_up(p_netif)) { + if (p_netif != NULL && netif_is_up(p_netif)) { netif_create_ip6_linklocal_address(p_netif, 1); nd6_set_cb(p_netif, tcpip_adapter_nd6_cb); @@ -353,23 +361,20 @@ esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_option_mode_t opt_op, tcpip_a } switch (opt_id) { - case IP_ADDRESS_LEASE_TIME: - { - *(uint32_t*)opt_val = *(uint32_t*)opt_info; - break; - } - case REQUESTED_IP_ADDRESS: - { - memcpy(opt_val, opt_info, opt_len); - break; - } - case ROUTER_SOLICITATION_ADDRESS: - { - *(uint8_t *)opt_val = (*(uint8_t *)opt_info) & OFFER_ROUTER; - break; - } - default: - break; + case IP_ADDRESS_LEASE_TIME: { + *(uint32_t *)opt_val = *(uint32_t *)opt_info; + break; + } + case REQUESTED_IP_ADDRESS: { + memcpy(opt_val, opt_info, opt_len); + break; + } + case ROUTER_SOLICITATION_ADDRESS: { + *(uint8_t *)opt_val = (*(uint8_t *)opt_info) & OFFER_ROUTER; + break; + } + default: + break; } } else if (opt_op == TCPIP_ADAPTER_OP_SET) { if (dhcps_status == TCPIP_ADAPTER_DHCP_STARTED) { @@ -377,55 +382,54 @@ esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_option_mode_t opt_op, tcpip_a } switch (opt_id) { - case IP_ADDRESS_LEASE_TIME: - { - if (*(uint32_t*)opt_val != 0) - *(uint32_t*)opt_info = *(uint32_t*)opt_val; - else - *(uint32_t*)opt_info = DHCPS_LEASE_TIME_DEF; - break; + case IP_ADDRESS_LEASE_TIME: { + if (*(uint32_t *)opt_val != 0) { + *(uint32_t *)opt_info = *(uint32_t *)opt_val; + } else { + *(uint32_t *)opt_info = DHCPS_LEASE_TIME_DEF; } - case REQUESTED_IP_ADDRESS: - { - tcpip_adapter_ip_info_t info; - uint32_t softap_ip = 0; - uint32_t start_ip = 0; - uint32_t end_ip = 0; - dhcps_lease_t *poll = opt_val; - - if (poll->enable){ - memset(&info, 0x00, sizeof(tcpip_adapter_ip_info_t)); - tcpip_adapter_get_ip_info(WIFI_IF_AP, &info); - softap_ip = htonl(info.ip.addr); - start_ip = htonl(poll->start_ip.addr); - end_ip = htonl(poll->end_ip.addr); + break; + } + case REQUESTED_IP_ADDRESS: { + tcpip_adapter_ip_info_t info; + uint32_t softap_ip = 0; + uint32_t start_ip = 0; + uint32_t end_ip = 0; + dhcps_lease_t *poll = opt_val; - /*config ip information can't contain local ip*/ - if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) - return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + if (poll->enable) { + memset(&info, 0x00, sizeof(tcpip_adapter_ip_info_t)); + tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &info); + softap_ip = htonl(info.ip.addr); + start_ip = htonl(poll->start_ip.addr); + end_ip = htonl(poll->end_ip.addr); - /*config ip information must be in the same segment as the local ip*/ - softap_ip >>= 8; - if ((start_ip >> 8 != softap_ip) + /*config ip information can't contain local ip*/ + if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + + /*config ip information must be in the same segment as the local ip*/ + softap_ip >>= 8; + if ((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) { - return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; - } + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } - if (end_ip - start_ip > DHCPS_MAX_LEASE) { - return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; - } - } + if (end_ip - start_ip > DHCPS_MAX_LEASE) { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + } - memcpy(opt_info, opt_val, opt_len); - break; - } - case ROUTER_SOLICITATION_ADDRESS: - { - *(uint8_t *)opt_info = (*(uint8_t *)opt_val) & OFFER_ROUTER; - break; - } - default: - break; + memcpy(opt_info, opt_val, opt_len); + break; + } + case ROUTER_SOLICITATION_ADDRESS: { + *(uint8_t *)opt_info = (*(uint8_t *)opt_val) & OFFER_ROUTER; + break; + } + default: + break; } } else { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; @@ -454,7 +458,7 @@ esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if) if (p_netif != NULL && netif_is_up(p_netif)) { tcpip_adapter_ip_info_t default_ip; - tcpip_adapter_get_ip_info(WIFI_IF_AP, &default_ip); + tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &default_ip); dhcps_start(p_netif, default_ip.ip); dhcps_status = TCPIP_ADAPTER_DHCP_STARTED; TCPIP_ADAPTER_DEBUG("dhcp server start successfully\n"); @@ -503,22 +507,25 @@ esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode_t opt_op, tcpip_a return ESP_OK; } -static void tcpip_adapter_dhcpc_cb(void) +static void tcpip_adapter_dhcpc_cb(struct netif *netif) { - struct netif *netif = esp_netif[TCPIP_ADAPTER_IF_STA]; - if (!netif) { TCPIP_ADAPTER_DEBUG("null netif=%p\n", netif); return; } + if (netif != esp_netif[TCPIP_ADAPTER_IF_STA] && netif != esp_netif[TCPIP_ADAPTER_IF_ETH]) { + TCPIP_ADAPTER_DEBUG("err netif=%p\n", netif); + return; + } + if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY) ) { tcpip_adapter_ip_info_t *ip_info = &esp_ip[TCPIP_ADAPTER_IF_STA]; //check whether IP is changed if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), &ip_info->ip) || - !ip4_addr_cmp(ip_2_ip4(&netif->netmask), &ip_info->netmask) || - !ip4_addr_cmp(ip_2_ip4(&netif->gw), &ip_info->gw) ) { + !ip4_addr_cmp(ip_2_ip4(&netif->netmask), &ip_info->netmask) || + !ip4_addr_cmp(ip_2_ip4(&netif->gw), &ip_info->gw) ) { system_event_t evt; ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr)); @@ -526,7 +533,12 @@ static void tcpip_adapter_dhcpc_cb(void) ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw)); //notify event - evt.event_id = SYSTEM_EVENT_STA_GOT_IP; + if (netif == esp_netif[TCPIP_ADAPTER_IF_STA]) { + evt.event_id = SYSTEM_EVENT_STA_GOT_IP; + } else if (netif == esp_netif[TCPIP_ADAPTER_IF_ETH]) { + evt.event_id = SYSTEM_EVENT_ETH_GOT_IP; + } + memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t)); esp_event_send(&evt); @@ -540,7 +552,7 @@ static void tcpip_adapter_dhcpc_cb(void) esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status) { - *status = dhcpc_status; + *status = dhcpc_status[tcpip_if]; return ESP_OK; } @@ -548,12 +560,12 @@ esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adap esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if) { /* only support sta now, need to support ethernet */ - if (tcpip_if != TCPIP_ADAPTER_IF_STA || tcpip_if >= TCPIP_ADAPTER_IF_MAX) { + if ((tcpip_if != TCPIP_ADAPTER_IF_STA && tcpip_if != TCPIP_ADAPTER_IF_ETH) || tcpip_if >= TCPIP_ADAPTER_IF_MAX) { TCPIP_ADAPTER_DEBUG("dhcp client invalid if=%d\n", tcpip_if); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } - if (dhcpc_status != TCPIP_ADAPTER_DHCP_STARTED) { + if (dhcpc_status[tcpip_if] != TCPIP_ADAPTER_DHCP_STARTED) { struct netif *p_netif = esp_netif[tcpip_if]; ip4_addr_set_zero(&esp_ip[tcpip_if].ip); @@ -568,7 +580,7 @@ esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if) ip_addr_set_zero(&p_netif->gw); } else { TCPIP_ADAPTER_DEBUG("dhcp client re init\n"); - dhcpc_status = TCPIP_ADAPTER_DHCP_INIT; + dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; return ESP_OK; } @@ -580,11 +592,11 @@ esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if) dhcp_set_cb(p_netif, tcpip_adapter_dhcpc_cb); TCPIP_ADAPTER_DEBUG("dhcp client start successfully\n"); - dhcpc_status = TCPIP_ADAPTER_DHCP_STARTED; + dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STARTED; return ESP_OK; } else { TCPIP_ADAPTER_DEBUG("dhcp client re init\n"); - dhcpc_status = TCPIP_ADAPTER_DHCP_INIT; + dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; return ESP_OK; } } @@ -601,7 +613,7 @@ esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if) return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } - if (dhcpc_status == TCPIP_ADAPTER_DHCP_STARTED) { + if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) { struct netif *p_netif = esp_netif[tcpip_if]; if (p_netif != NULL) { @@ -614,13 +626,19 @@ esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if) TCPIP_ADAPTER_DEBUG("dhcp client if not ready\n"); return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } - } else if (dhcpc_status == TCPIP_ADAPTER_DHCP_STOPPED) { + } else if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STOPPED) { TCPIP_ADAPTER_DEBUG("dhcp client already stoped\n"); return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED; } TCPIP_ADAPTER_DEBUG("dhcp client stop successfully\n"); - dhcpc_status = TCPIP_ADAPTER_DHCP_STOPPED; + dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED; + return ESP_OK; +} + +esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb) +{ + ethernetif_input(esp_netif[TCPIP_ADAPTER_IF_ETH], buffer, len); return ESP_OK; } @@ -644,29 +662,32 @@ bool tcpip_dep_output(wifi_interface_t wifi_if, void *buffer, uint16_t len) } #endif -wifi_interface_t tcpip_adapter_get_wifi_if(void *dev) +esp_interface_t tcpip_adapter_get_esp_if(void *dev) { struct netif *p_netif = (struct netif *)dev; if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) { - return WIFI_IF_STA; + return ESP_IF_WIFI_STA; } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) { - return WIFI_IF_AP; + return ESP_IF_WIFI_AP; + } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_ETH]) { + return ESP_IF_ETH; } - return WIFI_IF_MAX; + return ESP_IF_MAX; } esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list) { int i; - if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL)) + if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL)) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } memset(tcpip_sta_list, 0, sizeof(tcpip_adapter_sta_list_t)); tcpip_sta_list->num = wifi_sta_list->num; - for (i=0; inum; i++){ + for (i = 0; i < wifi_sta_list->num; i++) { memcpy(tcpip_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6); dhcp_search_ip_on_mac(tcpip_sta_list->sta[i].mac, &tcpip_sta_list->sta[i].ip); } diff --git a/docs/Doxyfile b/docs/Doxyfile old mode 100644 new mode 100755 index 2a40898197..962a17543d --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -24,7 +24,8 @@ INPUT = ../components/esp32/include/esp_wifi.h \ ../components/spi_flash/include \ ../components/esp32/include/esp_int_wdt.h \ ../components/esp32/include/esp_task_wdt.h \ - ../components/app_update/include/esp_ota_ops.h + ../components/app_update/include/esp_ota_ops.h \ + ../components/ethernet/include/esp_eth.h ## Get warnings for functions that have no documentation for their parameters or return value ## diff --git a/docs/api/esp_eth.rst b/docs/api/esp_eth.rst new file mode 100644 index 0000000000..f8f19092d1 --- /dev/null +++ b/docs/api/esp_eth.rst @@ -0,0 +1,51 @@ +ETHERNET +======== + +Application Example +------------------- + +ethernet example: `examples/14_ethernet `_. + +API Reference +------------- + +Header Files +^^^^^^^^^^^^ + + * `components/ethernet/include/esp_eth.h `_ + +Macros +^^^^^^ + + +Type Definitions +^^^^^^^^^^^^^^^^ + +.. doxygentypedef:: eth_phy_fun +.. doxygentypedef:: eth_tcpip_input_fun +.. doxygentypedef:: eth_gpio_config_func + +Enumerations +^^^^^^^^^^^^ + +.. doxygenenum:: eth_mode_t +.. doxygenenum:: eth_phy_base_t + +Structures +^^^^^^^^^^ + +.. doxygenstruct:: eth_config_t + :members: + + +Functions +^^^^^^^^^ + +.. doxygenfunction:: esp_eth_init +.. doxygenfunction:: esp_eth_tx +.. doxygenfunction:: esp_eth_enable +.. doxygenfunction:: esp_eth_disable +.. doxygenfunction:: esp_eth_get_mac +.. doxygenfunction:: esp_eth_smi_write +.. doxygenfunction:: esp_eth_smi_read + diff --git a/docs/index.rst b/docs/index.rst old mode 100644 new mode 100755 index da11f32237..be6a372b4b --- a/docs/index.rst +++ b/docs/index.rst @@ -108,6 +108,7 @@ Contents: Logging Non-Volatile Storage Virtual Filesystem + Ethernet deep-sleep-stub Template diff --git a/examples/03_http_request/main/http_request_main.c b/examples/03_http_request/main/http_request_main.c index 2c203f8394..9fe1933373 100644 --- a/examples/03_http_request/main/http_request_main.c +++ b/examples/03_http_request/main/http_request_main.c @@ -88,7 +88,7 @@ static void initialise_wifi(void) }; ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_ERROR_CHECK( esp_wifi_start() ); } diff --git a/examples/04_https_request/main/https_request_main.c b/examples/04_https_request/main/https_request_main.c index 1f7112bc86..1d6115d08c 100644 --- a/examples/04_https_request/main/https_request_main.c +++ b/examples/04_https_request/main/https_request_main.c @@ -169,7 +169,7 @@ static void initialise_wifi(void) }; ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_ERROR_CHECK( esp_wifi_start() ); } diff --git a/examples/06_sntp/main/sntp_main.c b/examples/06_sntp/main/sntp_main.c index 6827fa9378..c3edb9e2bd 100644 --- a/examples/06_sntp/main/sntp_main.c +++ b/examples/06_sntp/main/sntp_main.c @@ -136,7 +136,7 @@ static void initialise_wifi(void) }; ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_ERROR_CHECK( esp_wifi_start() ); } diff --git a/examples/09_openssl_client/main/openssl_client.c b/examples/09_openssl_client/main/openssl_client.c index c6b0e449ac..69e16141be 100644 --- a/examples/09_openssl_client/main/openssl_client.c +++ b/examples/09_openssl_client/main/openssl_client.c @@ -213,7 +213,7 @@ static void wifi_conn_init(void) }, }; ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_LOGI(TAG, "start the WIFI SSID:[%s] password:[%s]\n", EXAMPLE_WIFI_SSID, EXAMPLE_WIFI_PASS); ESP_ERROR_CHECK( esp_wifi_start() ); } diff --git a/examples/10_openssl_server/main/openssl_server.c b/examples/10_openssl_server/main/openssl_server.c index 53b6050d57..756c1407f5 100644 --- a/examples/10_openssl_server/main/openssl_server.c +++ b/examples/10_openssl_server/main/openssl_server.c @@ -236,7 +236,7 @@ static void wifi_conn_init(void) }, }; ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_LOGI(TAG, "start the WIFI SSID:[%s] password:[%s]\n", EXAMPLE_WIFI_SSID, EXAMPLE_WIFI_PASS); ESP_ERROR_CHECK( esp_wifi_start() ); } diff --git a/examples/14_ethernet/Makefile b/examples/14_ethernet/Makefile new file mode 100644 index 0000000000..f16d4d2d7a --- /dev/null +++ b/examples/14_ethernet/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := ethernet_demo + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/14_ethernet/README.md b/examples/14_ethernet/README.md new file mode 100644 index 0000000000..71c2590457 --- /dev/null +++ b/examples/14_ethernet/README.md @@ -0,0 +1,6 @@ +# ethernet Example + +Init ethernet interface and enable it ,then you can ping it if it got ip address. + + +See the README.md file in the upper level 'examples' directory for more information about examples. diff --git a/examples/14_ethernet/main/component.mk b/examples/14_ethernet/main/component.mk new file mode 100644 index 0000000000..a98f634eae --- /dev/null +++ b/examples/14_ethernet/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/14_ethernet/main/ethernet_main.c b/examples/14_ethernet/main/ethernet_main.c new file mode 100644 index 0000000000..836e977f48 --- /dev/null +++ b/examples/14_ethernet/main/ethernet_main.c @@ -0,0 +1,112 @@ +/* ethernet Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "esp_system.h" +#include "esp_err.h" +#include "esp_event_loop.h" +#include "esp_event.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_eth.h" + +#include "rom/ets_sys.h" +#include "rom/gpio.h" + +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/gpio_reg.h" +#include "soc/gpio_sig_map.h" + +#include "tcpip_adapter.h" +#include "nvs_flash.h" +#include "driver/gpio.h" + +static const char *TAG = "eth_demo"; + +void phy_tlk110_init(void) +{ + esp_eth_smi_write(0x1f, 0x8000); + ets_delay_us(20000); + + while (esp_eth_smi_read(0x2) != 0x2000) { + } + + esp_eth_smi_write(0x9, 0x7400); + esp_eth_smi_write(0x9, 0xf400); + ets_delay_us(20000); +} + +void eth_gpio_config_rmii(void) +{ + //txd0 to gpio19 ,can not change + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, 5); + //rx_en to gpio21 ,can not change + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO21_U, 5); + //txd1 to gpio22 , can not change + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO22_U, 5); + //rxd0 to gpio25 , can not change + gpio_set_direction(25, GPIO_MODE_INPUT); + //rxd1 to gpio26 ,can not change + gpio_set_direction(26, GPIO_MODE_INPUT); + //rmii clk ,can not change + gpio_set_direction(0, GPIO_MODE_INPUT); + + //mdc to gpio4 + gpio_matrix_out(4, EMAC_MDC_O_IDX, 0, 0); + //mdio to gpio2 + gpio_matrix_out(2, EMAC_MDO_O_IDX, 0, 0); + gpio_matrix_in(2, EMAC_MDI_I_IDX, 0); +} + +void eth_task(void *pvParameter) +{ + tcpip_adapter_ip_info_t ip; + memset(&ip, 0, sizeof(tcpip_adapter_ip_info_t)); + vTaskDelay(2000 / portTICK_RATE_MS); + + while (1) { + + vTaskDelay(2000 / portTICK_RATE_MS); + + if (tcpip_adapter_get_ip_info(ESP_IF_ETH, &ip) == 0) { + ESP_LOGI(TAG, "\n~~~~~~~~~~~\n"); + 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"); + } + } +} + +void app_main() +{ + esp_err_t ret = ESP_OK; + 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; + config.gpio_config = eth_gpio_config_rmii; + config.tcpip_input = tcpip_adapter_eth_input; + + ret = esp_eth_init(&config); + if(ret == ESP_OK) { + esp_eth_enable(); + xTaskCreate(eth_task, "eth_task", 2048, NULL, (tskIDLE_PRIORITY + 2), NULL); + } + +}