ethernet: add first version of ethernet driver

This commit is contained in:
shangke 2016-11-08 17:45:17 +08:00 committed by Wu Jian Gang
parent c110795718
commit e0040af7e5
36 changed files with 3080 additions and 126 deletions

View File

@ -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, &eth_ip);
tcpip_adapter_start(TCPIP_ADAPTER_IF_ETH, eth_mac, &eth_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, &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, &eth_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;

View File

@ -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;

View File

@ -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 <stdint.h>
#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__ */

View File

@ -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] */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1,5 @@
#
# Component Makefile
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@ -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 <stdint.h>
#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

View File

@ -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

View File

@ -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 <stdio.h>
#include <string.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 "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);
}

View File

@ -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 <stdint.h>
#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

View File

@ -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 <stdio.h>
#include <string.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/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;
}

View File

@ -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 <stdint.h>
#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

View File

@ -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;

View File

@ -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. */
}

View File

@ -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);

View File

@ -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_ */

View File

@ -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_

View File

@ -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 <adam@sics.se>
*
*/
#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 <stdio.h>
#include <string.h>
#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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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; i<wifi_sta_list->num; 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);
}

3
docs/Doxyfile Normal file → Executable file
View File

@ -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
##

51
docs/api/esp_eth.rst Normal file
View File

@ -0,0 +1,51 @@
ETHERNET
========
Application Example
-------------------
ethernet example: `examples/14_ethernet <https://github.com/espressif/esp-idf/tree/master/examples/14_ethernet>`_.
API Reference
-------------
Header Files
^^^^^^^^^^^^
* `components/ethernet/include/esp_eth.h <https://github.com/espressif/esp-idf/blob/master/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

1
docs/index.rst Normal file → Executable file
View File

@ -108,6 +108,7 @@ Contents:
Logging <api/log>
Non-Volatile Storage <api/nvs_flash>
Virtual Filesystem <api/vfs>
Ethernet <api/esp_eth>
deep-sleep-stub
Template <api/template>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@ -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 <stdio.h>
#include <string.h>
#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);
}
}