feat(esp_eth): a new folder structure of the driver and other improvements
Fixed memory leak in emac_esp_new_dma function. Polished ESP EMAC cache management. Added emac_periph definitions based on SoC features and improved(generalized) ESP EMAC GPIO initialization. Added ESP EMAC GPIO reservation. Added check for frame error condition indicated by EMAC DMA and created a target test.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -14,6 +14,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Offset for start of MAC custom ioctl commands
|
||||
*
|
||||
*/
|
||||
#define ETH_CMD_CUSTOM_MAC_CMDS_OFFSET 0x0FFF
|
||||
/**
|
||||
* @brief Offset for start of PHY custom ioctl commands
|
||||
*
|
||||
*/
|
||||
#define ETH_CMD_CUSTOM_PHY_CMDS_OFFSET 0x1FFF
|
||||
|
||||
/**
|
||||
* @brief Ethernet driver state
|
||||
*
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_eth_com.h"
|
||||
#include "esp_eth_mac.h"
|
||||
#if CONFIG_ETH_USE_SPI_ETHERNET
|
||||
#include "esp_eth_mac_spi.h"
|
||||
#endif // CONFIG_ETH_USE_SPI_ETHERNET
|
||||
#if CONFIG_ETH_USE_ESP32_EMAC
|
||||
#include "esp_eth_mac_esp.h"
|
||||
#endif // CONFIG_ETH_USE_ESP32_EMAC
|
||||
#if CONFIG_ETH_USE_OPENETH
|
||||
#include "esp_eth_mac_openeth.h"
|
||||
#endif // CONFIG_ETH_USE_OPENETH
|
||||
#include "esp_eth_phy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -151,8 +159,8 @@ typedef enum {
|
||||
ETH_CMD_READ_PHY_REG, /*!< Read PHY register */
|
||||
ETH_CMD_WRITE_PHY_REG, /*!< Write PHY register */
|
||||
|
||||
ETH_CMD_CUSTOM_MAC_CMDS = 0x0FFF, // Offset for start of MAC custom commands
|
||||
ETH_CMD_CUSTOM_PHY_CMDS = 0x1FFF, // Offset for start of PHY custom commands
|
||||
ETH_CMD_CUSTOM_MAC_CMDS = ETH_CMD_CUSTOM_MAC_CMDS_OFFSET, // Offset for start of MAC custom commands
|
||||
ETH_CMD_CUSTOM_PHY_CMDS = ETH_CMD_CUSTOM_PHY_CMDS_OFFSET, // Offset for start of PHY custom commands
|
||||
} esp_eth_io_cmd_t;
|
||||
|
||||
/**
|
||||
@@ -272,7 +280,7 @@ esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, size_t length);
|
||||
* @param[in] argc number variable arguments
|
||||
* @param ... variable arguments
|
||||
* @return
|
||||
* - ESP_OK: transmit successfull
|
||||
* - ESP_OK: transmit successful
|
||||
* - ESP_ERR_INVALID_STATE: invalid driver state (e.i. driver is not started)
|
||||
* - ESP_ERR_TIMEOUT: transmit frame buffer failed because HW was not get available in predefined period
|
||||
* - ESP_FAIL: transmit frame buffer failed because some other error occurred
|
||||
@@ -280,7 +288,7 @@ esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, size_t length);
|
||||
esp_err_t esp_eth_transmit_vargs(esp_eth_handle_t hdl, uint32_t argc, ...);
|
||||
|
||||
/**
|
||||
* @brief Misc IO function of Etherent driver
|
||||
* @brief Misc IO function of Ethernet driver
|
||||
*
|
||||
* @param[in] hdl: handle of Ethernet driver
|
||||
* @param[in] cmd: IO control command
|
||||
@@ -314,6 +322,28 @@ esp_err_t esp_eth_transmit_vargs(esp_eth_handle_t hdl, uint32_t argc, ...);
|
||||
*/
|
||||
esp_err_t esp_eth_ioctl(esp_eth_handle_t hdl, esp_eth_io_cmd_t cmd, void *data);
|
||||
|
||||
/**
|
||||
* @brief Get PHY instance memory address
|
||||
*
|
||||
* @param[in] hdl handle of Ethernet driver
|
||||
* @param[out] phy pointer to memory to store the instance
|
||||
* @return esp_err_t
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_ARG: failed because of some invalid argument
|
||||
*/
|
||||
esp_err_t esp_eth_get_phy_instance(esp_eth_handle_t hdl, esp_eth_phy_t **phy);
|
||||
|
||||
/**
|
||||
* @brief Get MAC instance memory address
|
||||
*
|
||||
* @param[in] hdl handle of Ethernet driver
|
||||
* @param[out] mac pointer to memory to store the instance
|
||||
* @return esp_err_t
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_ARG: failed because of some invalid argument
|
||||
*/
|
||||
esp_err_t esp_eth_get_mac_instance(esp_eth_handle_t hdl, esp_eth_mac_t **mac);
|
||||
|
||||
/**
|
||||
* @brief Increase Ethernet driver reference
|
||||
* @note Ethernet driver handle can be obtained by os timer, netif, etc.
|
||||
|
||||
@@ -9,9 +9,6 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_eth_com.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_ETH_USE_SPI_ETHERNET
|
||||
#include "driver/spi_master.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -306,7 +303,7 @@ struct esp_eth_mac_s {
|
||||
* - ESP_FAIL: process io command failed because some other error occurred
|
||||
* - ESP_ERR_NOT_SUPPORTED: requested feature is not supported
|
||||
*/
|
||||
esp_err_t (*custom_ioctl)(esp_eth_mac_t *mac, uint32_t cmd, void *data);
|
||||
esp_err_t (*custom_ioctl)(esp_eth_mac_t *mac, int cmd, void *data);
|
||||
|
||||
/**
|
||||
* @brief Free memory of Ethernet MAC
|
||||
@@ -321,115 +318,6 @@ struct esp_eth_mac_s {
|
||||
esp_err_t (*del)(esp_eth_mac_t *mac);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief RMII Clock Mode Options
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief Default values configured using Kconfig are going to be used when "Default" selected.
|
||||
*
|
||||
* @note May not be supported on all targets.
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_DEFAULT,
|
||||
|
||||
/**
|
||||
* @brief Input RMII Clock from external. EMAC Clock GPIO number needs to be configured when this option is selected.
|
||||
*
|
||||
* @note MAC will get RMII clock from outside. Note that ESP32 only supports GPIO0 to input the RMII clock.
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_EXT_IN,
|
||||
|
||||
/**
|
||||
* @brief Output RMII Clock from internal (A/M)PLL Clock. EMAC Clock GPIO number needs to be configured when this option is selected.
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_OUT
|
||||
} emac_rmii_clock_mode_t;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
/**
|
||||
* @brief RMII Clock GPIO number Options for ESP32
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief MAC will get RMII clock from outside at this GPIO.
|
||||
*
|
||||
* @note ESP32 only supports GPIO0 to input the RMII clock.
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_IN_GPIO = 0,
|
||||
|
||||
/**
|
||||
* @brief Output RMII Clock from internal APLL Clock available at GPIO0
|
||||
*
|
||||
* @note GPIO0 can be set to output a pre-divided PLL clock (test only!). Enabling this option will configure GPIO0 to output a 50MHz clock.
|
||||
* In fact this clock doesn’t have directly relationship with EMAC peripheral. Sometimes this clock won’t work well with your PHY chip.
|
||||
* You might need to add some extra devices after GPIO0 (e.g. inverter). Note that outputting RMII clock on GPIO0 is an experimental practice.
|
||||
* If you want the Ethernet to work with WiFi, don’t select GPIO0 output mode for stability.
|
||||
*
|
||||
*/
|
||||
EMAC_APPL_CLK_OUT_GPIO = 0,
|
||||
|
||||
/**
|
||||
* @brief Output RMII Clock from internal APLL Clock available at GPIO16
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_OUT_GPIO = 16,
|
||||
|
||||
/**
|
||||
* @brief Inverted Output RMII Clock from internal APLL Clock available at GPIO17
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_OUT_180_GPIO = 17
|
||||
} emac_rmii_clock_gpio_t;
|
||||
#else
|
||||
/**
|
||||
* @brief RMII Clock GPIO number
|
||||
*
|
||||
*/
|
||||
typedef int emac_rmii_clock_gpio_t;
|
||||
#endif // CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
/**
|
||||
* @brief Ethernet MAC Clock Configuration
|
||||
*
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
// MII interface is not fully implemented...
|
||||
// Reserved for GPIO number, clock source, etc. in MII mode
|
||||
} mii; /*!< EMAC MII Clock Configuration */
|
||||
struct {
|
||||
emac_rmii_clock_mode_t clock_mode; /*!< RMII Clock Mode Configuration */
|
||||
emac_rmii_clock_gpio_t clock_gpio; /*!< RMII Clock GPIO Configuration */
|
||||
} rmii; /*!< EMAC RMII Clock Configuration */
|
||||
} eth_mac_clock_config_t;
|
||||
|
||||
#if SOC_EMAC_USE_IO_MUX
|
||||
/**
|
||||
* @brief Ethernet MAC MII/RMII data plane GPIO configuration
|
||||
*
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
// MII interface is not fully implemented...
|
||||
// Reserved for data interface GPIO numbers in MII mode
|
||||
} mii; /*!< EMAC MII Data GPIO Configuration */
|
||||
struct {
|
||||
int32_t tx_en_num; /*!< TX_EN GPIO number */
|
||||
int32_t txd0_num; /*!< TXD0 GPIO number */
|
||||
int32_t txd1_num; /*!< TXD1 GPIO number */
|
||||
int32_t crs_dv_num; /*!< CRS_DV GPIO number */
|
||||
int32_t rxd0_num; /*!< RXD0 GPIO number */
|
||||
int32_t rxd1_num; /*!< RXD1 GPIO number */
|
||||
} rmii; /*!< EMAC RMII Data GPIO Configuration */
|
||||
} eth_mac_dataif_gpio_config_t;
|
||||
#endif // SOC_EMAC_USE_IO_MUX
|
||||
|
||||
/**
|
||||
* @brief Configuration of Ethernet MAC object
|
||||
*
|
||||
@@ -456,327 +344,6 @@ typedef struct {
|
||||
.flags = 0, \
|
||||
}
|
||||
|
||||
#if CONFIG_ETH_USE_ESP32_EMAC
|
||||
/**
|
||||
* @brief EMAC specific configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int smi_mdc_gpio_num; /*!< SMI MDC GPIO number, set to -1 could bypass the SMI GPIO configuration */
|
||||
int smi_mdio_gpio_num; /*!< SMI MDIO GPIO number, set to -1 could bypass the SMI GPIO configuration */
|
||||
eth_data_interface_t interface; /*!< EMAC Data interface to PHY (MII/RMII) */
|
||||
eth_mac_clock_config_t clock_config; /*!< EMAC Interface clock configuration */
|
||||
eth_mac_dma_burst_len_t dma_burst_len; /*!< EMAC DMA burst length for both Tx and Rx */
|
||||
int intr_priority; /*!< EMAC interrupt priority, if set to 0 or a negative value, the driver will try to allocate an interrupt with a default priority */
|
||||
#if SOC_EMAC_USE_IO_MUX
|
||||
eth_mac_dataif_gpio_config_t emac_dataif_gpio; /*!< EMAC MII/RMII data plane GPIO configuration */
|
||||
#endif // SOC_EMAC_USE_IO_MUX
|
||||
#if !SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK
|
||||
eth_mac_clock_config_t clock_config_out_in; /*!< EMAC input clock configuration for internally generated output clock (when output clock is looped back externally) */
|
||||
#endif //SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK
|
||||
} eth_esp32_emac_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default ESP32's EMAC specific configuration
|
||||
*
|
||||
*/
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \
|
||||
{ \
|
||||
.smi_mdc_gpio_num = 23, \
|
||||
.smi_mdio_gpio_num = 18, \
|
||||
.interface = EMAC_DATA_INTERFACE_RMII, \
|
||||
.clock_config = \
|
||||
{ \
|
||||
.rmii = \
|
||||
{ \
|
||||
.clock_mode = EMAC_CLK_DEFAULT, \
|
||||
.clock_gpio = EMAC_CLK_IN_GPIO \
|
||||
} \
|
||||
}, \
|
||||
.dma_burst_len = ETH_DMA_BURST_LEN_32, \
|
||||
.intr_priority = 0, \
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \
|
||||
{ \
|
||||
.smi_mdc_gpio_num = 31, \
|
||||
.smi_mdio_gpio_num = 27, \
|
||||
.interface = EMAC_DATA_INTERFACE_RMII, \
|
||||
.clock_config = \
|
||||
{ \
|
||||
.rmii = \
|
||||
{ \
|
||||
.clock_mode = EMAC_CLK_EXT_IN, \
|
||||
.clock_gpio = 50 \
|
||||
} \
|
||||
}, \
|
||||
.clock_config_out_in = \
|
||||
{ \
|
||||
.rmii = \
|
||||
{ \
|
||||
.clock_mode = EMAC_CLK_DEFAULT, \
|
||||
.clock_gpio = -1 \
|
||||
} \
|
||||
}, \
|
||||
.dma_burst_len = ETH_DMA_BURST_LEN_32, \
|
||||
.intr_priority = 0, \
|
||||
.emac_dataif_gpio = \
|
||||
{ \
|
||||
.rmii = \
|
||||
{ \
|
||||
.tx_en_num = 49, \
|
||||
.txd0_num = 34, \
|
||||
.txd1_num = 35, \
|
||||
.crs_dv_num = 28, \
|
||||
.rxd0_num = 29, \
|
||||
.rxd1_num = 30 \
|
||||
} \
|
||||
}, \
|
||||
}
|
||||
#endif // CONFIG_IDF_TARGET_ESP32P4
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create ESP32 Ethernet MAC instance
|
||||
*
|
||||
* @param esp32_config: EMAC specific configuration
|
||||
* @param config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config, const eth_mac_config_t *config);
|
||||
#endif // CONFIG_ETH_USE_ESP32_EMAC
|
||||
|
||||
#if CONFIG_ETH_USE_SPI_ETHERNET
|
||||
/**
|
||||
* @brief Custom SPI Driver Configuration.
|
||||
* This structure declares configuration and callback functions to access Ethernet SPI module via
|
||||
* user's custom SPI driver.
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* @brief Custom driver specific configuration data used by `init()` function.
|
||||
*
|
||||
* @note Type and its content is fully under user's control
|
||||
*
|
||||
*/
|
||||
void *config;
|
||||
|
||||
/**
|
||||
* @brief Custom driver SPI Initialization
|
||||
*
|
||||
* @param[in] spi_config: Custom driver specific configuration
|
||||
*
|
||||
* @return
|
||||
* - spi_ctx: when initialization is successful, a pointer to context structure holding all variables
|
||||
* needed for subsequent SPI access operations (e.g. SPI bus identification, mutexes, etc.)
|
||||
* - NULL: driver initialization failed
|
||||
*
|
||||
* @note return type and its content is fully under user's control
|
||||
*/
|
||||
void *(*init)(const void *spi_config);
|
||||
|
||||
/**
|
||||
* @brief Custom driver De-initialization
|
||||
*
|
||||
* @param[in] spi_ctx: a pointer to driver specific context structure
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: driver de-initialization was successful
|
||||
* - ESP_FAIL: driver de-initialization failed
|
||||
* - any other failure codes are allowed to be used to provide failure isolation
|
||||
*/
|
||||
esp_err_t (*deinit)(void *spi_ctx);
|
||||
|
||||
/**
|
||||
* @brief Custom driver SPI read
|
||||
*
|
||||
* @note The read function is responsible to construct command, address and data fields
|
||||
* of the SPI frame in format expected by particular SPI Ethernet module
|
||||
*
|
||||
* @param[in] spi_ctx: a pointer to driver specific context structure
|
||||
* @param[in] cmd: command
|
||||
* @param[in] addr: register address
|
||||
* @param[out] data: read data
|
||||
* @param[in] data_len: read data length in bytes
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: read was successful
|
||||
* - ESP_FAIL: read failed
|
||||
* - any other failure codes are allowed to be used to provide failure isolation
|
||||
*/
|
||||
esp_err_t (*read)(void *spi_ctx, uint32_t cmd, uint32_t addr, void *data, uint32_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Custom driver SPI write
|
||||
*
|
||||
* @note The write function is responsible to construct command, address and data fields
|
||||
* of the SPI frame in format expected by particular SPI Ethernet module
|
||||
*
|
||||
* @param[in] spi_ctx: a pointer to driver specific context structure
|
||||
* @param[in] cmd: command
|
||||
* @param[in] addr: register address
|
||||
* @param[in] data: data to write
|
||||
* @param[in] data_len: length of data to write in bytes
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: write was successful
|
||||
* - ESP_FAIL: write failed
|
||||
* - any other failure codes are allowed to be used to provide failure isolation
|
||||
*/
|
||||
esp_err_t (*write)(void *spi_ctx, uint32_t cmd, uint32_t addr, const void *data, uint32_t data_len);
|
||||
} eth_spi_custom_driver_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default configuration of the custom SPI driver.
|
||||
* Internal ESP-IDF SPI Master driver is used by default.
|
||||
*
|
||||
*/
|
||||
#define ETH_DEFAULT_SPI \
|
||||
{ \
|
||||
.config = NULL, \
|
||||
.init = NULL, \
|
||||
.deinit = NULL, \
|
||||
.read = NULL, \
|
||||
.write = NULL \
|
||||
}
|
||||
#endif // CONFIG_ETH_USE_SPI_ETHERNET
|
||||
|
||||
#if CONFIG_ETH_SPI_ETHERNET_DM9051
|
||||
/**
|
||||
* @brief DM9051 specific configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */
|
||||
uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */
|
||||
spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined) */
|
||||
spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined) */
|
||||
eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */
|
||||
} eth_dm9051_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default DM9051 specific configuration
|
||||
*
|
||||
*/
|
||||
#define ETH_DM9051_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \
|
||||
{ \
|
||||
.int_gpio_num = 4, \
|
||||
.poll_period_ms = 0, \
|
||||
.spi_host_id = spi_host, \
|
||||
.spi_devcfg = spi_devcfg_p, \
|
||||
.custom_spi_driver = ETH_DEFAULT_SPI, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create DM9051 Ethernet MAC instance
|
||||
*
|
||||
* @param dm9051_config: DM9051 specific configuration
|
||||
* @param mac_config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config, const eth_mac_config_t *mac_config);
|
||||
#endif // CONFIG_ETH_SPI_ETHERNET_DM9051
|
||||
|
||||
#if CONFIG_ETH_SPI_ETHERNET_W5500
|
||||
/**
|
||||
* @brief W5500 specific configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */
|
||||
uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */
|
||||
spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined)*/
|
||||
spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined)*/
|
||||
eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */
|
||||
} eth_w5500_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default W5500 specific configuration
|
||||
*
|
||||
*/
|
||||
#define ETH_W5500_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \
|
||||
{ \
|
||||
.int_gpio_num = 4, \
|
||||
.poll_period_ms = 0, \
|
||||
.spi_host_id = spi_host, \
|
||||
.spi_devcfg = spi_devcfg_p, \
|
||||
.custom_spi_driver = ETH_DEFAULT_SPI, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create W5500 Ethernet MAC instance
|
||||
*
|
||||
* @param w5500_config: W5500 specific configuration
|
||||
* @param mac_config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_w5500(const eth_w5500_config_t *w5500_config, const eth_mac_config_t *mac_config);
|
||||
#endif // CONFIG_ETH_SPI_ETHERNET_W5500
|
||||
|
||||
#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
|
||||
/**
|
||||
* @brief KSZ8851SNL specific configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */
|
||||
uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */
|
||||
spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined) */
|
||||
spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined) */
|
||||
eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */
|
||||
} eth_ksz8851snl_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default KSZ8851SNL specific configuration
|
||||
*
|
||||
*/
|
||||
#define ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \
|
||||
{ \
|
||||
.int_gpio_num = 4, \
|
||||
.poll_period_ms = 0, \
|
||||
.spi_host_id = spi_host, \
|
||||
.spi_devcfg = spi_devcfg_p, \
|
||||
.custom_spi_driver = ETH_DEFAULT_SPI, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create KSZ8851SNL Ethernet MAC instance
|
||||
*
|
||||
* @param ksz8851snl_config: KSZ8851SNL specific configuration
|
||||
* @param mac_config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_ksz8851snl(const eth_ksz8851snl_config_t *ksz8851snl_config, const eth_mac_config_t *mac_config);
|
||||
#endif // CONFIG_ETH_SPI_ETHERNET_KSZ8851
|
||||
|
||||
#if CONFIG_ETH_USE_OPENETH
|
||||
/**
|
||||
* @brief Create OpenCores Ethernet MAC instance
|
||||
*
|
||||
* @param config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_openeth(const eth_mac_config_t *config);
|
||||
#endif // CONFIG_ETH_USE_OPENETH
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_eth_com.h"
|
||||
#include "esp_eth_mac.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_ETH_USE_ESP32_EMAC
|
||||
|
||||
/**
|
||||
* @brief RMII Clock Mode Options
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief Default values configured using Kconfig are going to be used when "Default" selected.
|
||||
*
|
||||
* @warning Deprecated option. Clock configuration using Kconfig is limitedly supported only for ESP32 SoC via @c ETH_ESP32_EMAC_DEFAULT_CONFIG
|
||||
* and is going to be reevaluated in the next major release.
|
||||
* Clock mode and clock GPIO number is supposed to be defined in `EMAC specific configuration` structure from user's code.
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_DEFAULT __attribute__((deprecated)), // IDF-9724
|
||||
|
||||
/**
|
||||
* @brief Input RMII Clock from external. EMAC Clock GPIO number needs to be configured when this option is selected.
|
||||
*
|
||||
* @note MAC will get RMII clock from outside. Note that ESP32 only supports GPIO0 to input the RMII clock.
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_EXT_IN,
|
||||
|
||||
/**
|
||||
* @brief Output RMII Clock from internal (A/M)PLL Clock. EMAC Clock GPIO number needs to be configured when this option is selected.
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_OUT
|
||||
} emac_rmii_clock_mode_t;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
/**
|
||||
* @brief RMII Clock GPIO number Options for ESP32
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief MAC will get RMII clock from outside at this GPIO.
|
||||
*
|
||||
* @note ESP32 only supports GPIO0 to input the RMII clock.
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_IN_GPIO = 0,
|
||||
|
||||
/**
|
||||
* @brief Output RMII Clock from internal APLL Clock available at GPIO0
|
||||
*
|
||||
* @note GPIO0 can be set to output a pre-divided PLL clock (test only!). Enabling this option will configure GPIO0 to output a 50MHz clock.
|
||||
* In fact this clock doesn’t have directly relationship with EMAC peripheral. Sometimes this clock won’t work well with your PHY chip.
|
||||
* You might need to add some extra devices after GPIO0 (e.g. inverter). Note that outputting RMII clock on GPIO0 is an experimental practice.
|
||||
* If you want the Ethernet to work with WiFi, don’t select GPIO0 output mode for stability.
|
||||
*
|
||||
*/
|
||||
EMAC_APPL_CLK_OUT_GPIO = 0,
|
||||
|
||||
/**
|
||||
* @brief Output RMII Clock from internal APLL Clock available at GPIO16
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_OUT_GPIO = 16,
|
||||
|
||||
/**
|
||||
* @brief Inverted Output RMII Clock from internal APLL Clock available at GPIO17
|
||||
*
|
||||
*/
|
||||
EMAC_CLK_OUT_180_GPIO = 17
|
||||
} emac_rmii_clock_gpio_t;
|
||||
#else
|
||||
/**
|
||||
* @brief RMII Clock GPIO number
|
||||
*
|
||||
*/
|
||||
typedef int emac_rmii_clock_gpio_t;
|
||||
#endif // CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
/**
|
||||
* @brief Ethernet MAC Clock Configuration
|
||||
*
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
// MII interface is not fully implemented...
|
||||
// Reserved for GPIO number, clock source, etc. in MII mode
|
||||
} mii; /*!< EMAC MII Clock Configuration */
|
||||
struct {
|
||||
emac_rmii_clock_mode_t clock_mode; /*!< RMII Clock Mode Configuration */
|
||||
emac_rmii_clock_gpio_t clock_gpio; /*!< RMII Clock GPIO Configuration */
|
||||
} rmii; /*!< EMAC RMII Clock Configuration */
|
||||
} eth_mac_clock_config_t;
|
||||
|
||||
/**
|
||||
* @brief EMAC SMI GPIO configuration
|
||||
*/
|
||||
typedef struct {
|
||||
int mdc_num; /*!< SMI MDC GPIO number, set to -1 could bypass the SMI GPIO configuration */
|
||||
int mdio_num; /*!< SMI MDIO GPIO number, set to -1 could bypass the SMI GPIO configuration */
|
||||
} emac_esp_smi_gpio_config_t;
|
||||
|
||||
/**
|
||||
* @brief EMAC MII data interface GPIO configuration
|
||||
*/
|
||||
typedef struct {
|
||||
int tx_clk_num; /*!< TX_CLK GPIO number */
|
||||
int tx_en_num; /*!< TX_EN GPIO number */
|
||||
int txd0_num; /*!< TXD0 GPIO number */
|
||||
int txd1_num; /*!< TXD1 GPIO number */
|
||||
int txd2_num; /*!< TXD2 GPIO number */
|
||||
int txd3_num; /*!< TXD3 GPIO number */
|
||||
int rx_clk_num; /*!< RX_CLK GPIO number */
|
||||
int rx_dv_num; /*!< RX_DV GPIO number */
|
||||
int rxd0_num; /*!< RXD0 GPIO number */
|
||||
int rxd1_num; /*!< RXD1 GPIO number */
|
||||
int rxd2_num; /*!< RXD2 GPIO number */
|
||||
int rxd3_num; /*!< RXD3 GPIO number */
|
||||
int col_in_num; /*!< COL_IN GPIO number */
|
||||
int crs_in_num; /*!< CRS_IN GPIO number */
|
||||
int tx_er_num; /*!< TX_ER GPIO number */
|
||||
int rx_er_num; /*!< RX_ER GPIO number */
|
||||
} eth_mac_mii_gpio_config_t;
|
||||
|
||||
/**
|
||||
* @brief EMAC RMII data interface GPIO configuration
|
||||
*/
|
||||
typedef struct {
|
||||
int tx_en_num; /*!< TX_EN GPIO number */
|
||||
int txd0_num; /*!< TXD0 GPIO number */
|
||||
int txd1_num; /*!< TXD1 GPIO number */
|
||||
int crs_dv_num; /*!< CRS_DV GPIO number */
|
||||
int rxd0_num; /*!< RXD0 GPIO number */
|
||||
int rxd1_num; /*!< RXD1 GPIO number */
|
||||
} eth_mac_rmii_gpio_config_t;
|
||||
|
||||
#if SOC_EMAC_USE_MULTI_IO_MUX || SOC_EMAC_MII_USE_GPIO_MATRIX
|
||||
/**
|
||||
* @brief Ethernet MAC MII/RMII data plane GPIO configuration
|
||||
*
|
||||
*/
|
||||
typedef union {
|
||||
eth_mac_mii_gpio_config_t mii; /*!< EMAC MII Data GPIO Configuration */
|
||||
eth_mac_rmii_gpio_config_t rmii; /*!< EMAC RMII Data GPIO Configuration */
|
||||
} eth_mac_dataif_gpio_config_t;
|
||||
#endif // SOC_EMAC_USE_MULTI_IO_MUX
|
||||
|
||||
/**
|
||||
* @brief EMAC specific configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
union {
|
||||
emac_esp_smi_gpio_config_t smi_gpio; /*!< SMI GPIO numbers */
|
||||
struct {
|
||||
int smi_mdc_gpio_num __attribute__((deprecated("Please use smi_gpio instead"))); /*!< SMI MDC GPIO number, set to -1 could bypass the SMI GPIO configuration */
|
||||
int smi_mdio_gpio_num __attribute__((deprecated("Please use smi_gpio instead"))); /*!< SMI MDIO GPIO number, set to -1 could bypass the SMI GPIO configuration */
|
||||
};
|
||||
};
|
||||
eth_data_interface_t interface; /*!< EMAC Data interface to PHY (MII/RMII) */
|
||||
eth_mac_clock_config_t clock_config; /*!< EMAC Interface clock configuration */
|
||||
eth_mac_dma_burst_len_t dma_burst_len; /*!< EMAC DMA burst length for both Tx and Rx */
|
||||
int intr_priority; /*!< EMAC interrupt priority, if set to 0 or a negative value, the driver will try to allocate an interrupt with a default priority */
|
||||
#if SOC_EMAC_USE_MULTI_IO_MUX || SOC_EMAC_MII_USE_GPIO_MATRIX
|
||||
eth_mac_dataif_gpio_config_t emac_dataif_gpio; /*!< EMAC MII/RMII data plane GPIO configuration */
|
||||
#endif // SOC_EMAC_USE_MULTI_IO_MUX
|
||||
#if !SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK
|
||||
eth_mac_clock_config_t clock_config_out_in; /*!< EMAC input clock configuration for internally generated output clock (when output clock is looped back externally) */
|
||||
#endif //SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK
|
||||
} eth_esp32_emac_config_t;
|
||||
|
||||
/**
|
||||
* @brief List of ESP EMAC specific commands for ioctl API
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ETH_MAC_ESP_CMD_SET_TDES0_CFG_BITS = ETH_CMD_CUSTOM_MAC_CMDS_OFFSET, /*!< Set Transmit Descriptor Word 0 control bit mask (debug option)*/
|
||||
ETH_MAC_ESP_CMD_CLEAR_TDES0_CFG_BITS, /*!< Clear Transmit Descriptor Word 0 control bit mask (debug option)*/
|
||||
ETH_MAC_ESP_CMD_PTP_ENABLE, /*!< Enable IEEE1588 Time stamping */
|
||||
} eth_mac_esp_io_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief Default ESP32's EMAC specific configuration
|
||||
*
|
||||
*/
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#if CONFIG_ETH_RMII_CLK_INPUT // IDF-9724
|
||||
#define DEFAULT_RMII_CLK_MODE EMAC_CLK_EXT_IN
|
||||
#if CONFIG_ETH_RMII_CLK_IN_GPIO == 0
|
||||
#define DEFAULT_RMII_CLK_GPIO CONFIG_ETH_RMII_CLK_IN_GPIO
|
||||
#else
|
||||
#error "ESP32 EMAC only support input RMII clock to GPIO0"
|
||||
#endif // CONFIG_ETH_RMII_CLK_IN_GPIO == 0
|
||||
#elif CONFIG_ETH_RMII_CLK_OUTPUT
|
||||
#define DEFAULT_RMII_CLK_MODE EMAC_CLK_OUT
|
||||
#if CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0
|
||||
#define DEFAULT_RMII_CLK_GPIO EMAC_APPL_CLK_OUT_GPIO
|
||||
#else
|
||||
#define DEFAULT_RMII_CLK_GPIO CONFIG_ETH_RMII_CLK_OUT_GPIO
|
||||
#endif // CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0
|
||||
#else
|
||||
#error "Unsupported RMII clock mode"
|
||||
#endif // CONFIG_ETH_RMII_CLK_INPUT
|
||||
|
||||
#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \
|
||||
{ \
|
||||
.smi_gpio = \
|
||||
{ \
|
||||
.mdc_num = 23, \
|
||||
.mdio_num = 18 \
|
||||
}, \
|
||||
.interface = EMAC_DATA_INTERFACE_RMII, \
|
||||
.clock_config = \
|
||||
{ \
|
||||
.rmii = \
|
||||
{ \
|
||||
.clock_mode = DEFAULT_RMII_CLK_MODE, \
|
||||
.clock_gpio = DEFAULT_RMII_CLK_GPIO \
|
||||
} \
|
||||
}, \
|
||||
.dma_burst_len = ETH_DMA_BURST_LEN_32, \
|
||||
.intr_priority = 0, \
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \
|
||||
{ \
|
||||
.smi_gpio = \
|
||||
{ \
|
||||
.mdc_num = 31, \
|
||||
.mdio_num = 27 \
|
||||
}, \
|
||||
.interface = EMAC_DATA_INTERFACE_RMII, \
|
||||
.clock_config = \
|
||||
{ \
|
||||
.rmii = \
|
||||
{ \
|
||||
.clock_mode = EMAC_CLK_EXT_IN, \
|
||||
.clock_gpio = 50 \
|
||||
} \
|
||||
}, \
|
||||
.clock_config_out_in = \
|
||||
{ \
|
||||
.rmii = \
|
||||
{ \
|
||||
.clock_mode = EMAC_CLK_EXT_IN, \
|
||||
.clock_gpio = -1 \
|
||||
} \
|
||||
}, \
|
||||
.dma_burst_len = ETH_DMA_BURST_LEN_32, \
|
||||
.intr_priority = 0, \
|
||||
.emac_dataif_gpio = \
|
||||
{ \
|
||||
.rmii = \
|
||||
{ \
|
||||
.tx_en_num = 49, \
|
||||
.txd0_num = 34, \
|
||||
.txd1_num = 35, \
|
||||
.crs_dv_num = 28, \
|
||||
.rxd0_num = 29, \
|
||||
.rxd1_num = 30 \
|
||||
} \
|
||||
}, \
|
||||
}
|
||||
#endif // CONFIG_IDF_TARGET_ESP32P4
|
||||
|
||||
/**
|
||||
* @brief Create ESP32 Ethernet MAC instance
|
||||
*
|
||||
* @param esp32_config: EMAC specific configuration
|
||||
* @param config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config, const eth_mac_config_t *config);
|
||||
#endif // CONFIG_ETH_USE_ESP32_EMAC
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_eth_com.h"
|
||||
#include "esp_eth_mac.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_ETH_USE_OPENETH
|
||||
/**
|
||||
* @brief Create OpenCores Ethernet MAC instance
|
||||
*
|
||||
* @param config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_openeth(const eth_mac_config_t *config);
|
||||
#endif // CONFIG_ETH_USE_OPENETH
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_eth_com.h"
|
||||
#include "esp_eth_mac.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_ETH_USE_SPI_ETHERNET
|
||||
|
||||
/**
|
||||
* @brief Custom SPI Driver Configuration.
|
||||
* This structure declares configuration and callback functions to access Ethernet SPI module via
|
||||
* user's custom SPI driver.
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* @brief Custom driver specific configuration data used by `init()` function.
|
||||
*
|
||||
* @note Type and its content is fully under user's control
|
||||
*
|
||||
*/
|
||||
void *config;
|
||||
|
||||
/**
|
||||
* @brief Custom driver SPI Initialization
|
||||
*
|
||||
* @param[in] spi_config: Custom driver specific configuration
|
||||
*
|
||||
* @return
|
||||
* - spi_ctx: when initialization is successful, a pointer to context structure holding all variables
|
||||
* needed for subsequent SPI access operations (e.g. SPI bus identification, mutexes, etc.)
|
||||
* - NULL: driver initialization failed
|
||||
*
|
||||
* @note return type and its content is fully under user's control
|
||||
*/
|
||||
void *(*init)(const void *spi_config);
|
||||
|
||||
/**
|
||||
* @brief Custom driver De-initialization
|
||||
*
|
||||
* @param[in] spi_ctx: a pointer to driver specific context structure
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: driver de-initialization was successful
|
||||
* - ESP_FAIL: driver de-initialization failed
|
||||
* - any other failure codes are allowed to be used to provide failure isolation
|
||||
*/
|
||||
esp_err_t (*deinit)(void *spi_ctx);
|
||||
|
||||
/**
|
||||
* @brief Custom driver SPI read
|
||||
*
|
||||
* @note The read function is responsible to construct command, address and data fields
|
||||
* of the SPI frame in format expected by particular SPI Ethernet module
|
||||
*
|
||||
* @param[in] spi_ctx: a pointer to driver specific context structure
|
||||
* @param[in] cmd: command
|
||||
* @param[in] addr: register address
|
||||
* @param[out] data: read data
|
||||
* @param[in] data_len: read data length in bytes
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: read was successful
|
||||
* - ESP_FAIL: read failed
|
||||
* - any other failure codes are allowed to be used to provide failure isolation
|
||||
*/
|
||||
esp_err_t (*read)(void *spi_ctx, uint32_t cmd, uint32_t addr, void *data, uint32_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Custom driver SPI write
|
||||
*
|
||||
* @note The write function is responsible to construct command, address and data fields
|
||||
* of the SPI frame in format expected by particular SPI Ethernet module
|
||||
*
|
||||
* @param[in] spi_ctx: a pointer to driver specific context structure
|
||||
* @param[in] cmd: command
|
||||
* @param[in] addr: register address
|
||||
* @param[in] data: data to write
|
||||
* @param[in] data_len: length of data to write in bytes
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: write was successful
|
||||
* - ESP_FAIL: write failed
|
||||
* - any other failure codes are allowed to be used to provide failure isolation
|
||||
*/
|
||||
esp_err_t (*write)(void *spi_ctx, uint32_t cmd, uint32_t addr, const void *data, uint32_t data_len);
|
||||
} eth_spi_custom_driver_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default configuration of the custom SPI driver.
|
||||
* Internal ESP-IDF SPI Master driver is used by default.
|
||||
*
|
||||
*/
|
||||
#define ETH_DEFAULT_SPI \
|
||||
{ \
|
||||
.config = NULL, \
|
||||
.init = NULL, \
|
||||
.deinit = NULL, \
|
||||
.read = NULL, \
|
||||
.write = NULL \
|
||||
}
|
||||
#endif // CONFIG_ETH_USE_SPI_ETHERNET
|
||||
|
||||
#if CONFIG_ETH_SPI_ETHERNET_DM9051
|
||||
/**
|
||||
* @brief DM9051 specific configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */
|
||||
uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */
|
||||
spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined) */
|
||||
spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined) */
|
||||
eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */
|
||||
} eth_dm9051_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default DM9051 specific configuration
|
||||
*
|
||||
*/
|
||||
#define ETH_DM9051_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \
|
||||
{ \
|
||||
.int_gpio_num = 4, \
|
||||
.poll_period_ms = 0, \
|
||||
.spi_host_id = spi_host, \
|
||||
.spi_devcfg = spi_devcfg_p, \
|
||||
.custom_spi_driver = ETH_DEFAULT_SPI, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create DM9051 Ethernet MAC instance
|
||||
*
|
||||
* @param dm9051_config: DM9051 specific configuration
|
||||
* @param mac_config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config, const eth_mac_config_t *mac_config);
|
||||
#endif // CONFIG_ETH_SPI_ETHERNET_DM9051
|
||||
|
||||
#if CONFIG_ETH_SPI_ETHERNET_W5500
|
||||
/**
|
||||
* @brief W5500 specific configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */
|
||||
uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */
|
||||
spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined)*/
|
||||
spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined)*/
|
||||
eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */
|
||||
} eth_w5500_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default W5500 specific configuration
|
||||
*
|
||||
*/
|
||||
#define ETH_W5500_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \
|
||||
{ \
|
||||
.int_gpio_num = 4, \
|
||||
.poll_period_ms = 0, \
|
||||
.spi_host_id = spi_host, \
|
||||
.spi_devcfg = spi_devcfg_p, \
|
||||
.custom_spi_driver = ETH_DEFAULT_SPI, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create W5500 Ethernet MAC instance
|
||||
*
|
||||
* @param w5500_config: W5500 specific configuration
|
||||
* @param mac_config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_w5500(const eth_w5500_config_t *w5500_config, const eth_mac_config_t *mac_config);
|
||||
#endif // CONFIG_ETH_SPI_ETHERNET_W5500
|
||||
|
||||
#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
|
||||
/**
|
||||
* @brief KSZ8851SNL specific configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */
|
||||
uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */
|
||||
spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined) */
|
||||
spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined) */
|
||||
eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */
|
||||
} eth_ksz8851snl_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default KSZ8851SNL specific configuration
|
||||
*
|
||||
*/
|
||||
#define ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \
|
||||
{ \
|
||||
.int_gpio_num = 4, \
|
||||
.poll_period_ms = 0, \
|
||||
.spi_host_id = spi_host, \
|
||||
.spi_devcfg = spi_devcfg_p, \
|
||||
.custom_spi_driver = ETH_DEFAULT_SPI, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create KSZ8851SNL Ethernet MAC instance
|
||||
*
|
||||
* @param ksz8851snl_config: KSZ8851SNL specific configuration
|
||||
* @param mac_config: Ethernet MAC configuration
|
||||
*
|
||||
* @return
|
||||
* - instance: create MAC instance successfully
|
||||
* - NULL: create MAC instance failed because some error occurred
|
||||
*/
|
||||
esp_eth_mac_t *esp_eth_mac_new_ksz8851snl(const eth_ksz8851snl_config_t *ksz8851snl_config, const eth_mac_config_t *mac_config);
|
||||
#endif // CONFIG_ETH_SPI_ETHERNET_KSZ8851
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@ extern "C" {
|
||||
#define ESP_ETH_PHY_ADDR_AUTO (-1)
|
||||
|
||||
/**
|
||||
* @brief Auto-negotiation controll commands
|
||||
* @brief Auto-negotiation control commands
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
@@ -253,7 +253,7 @@ struct esp_eth_phy_s {
|
||||
* - ESP_FAIL: process io command failed because some other error occurred
|
||||
* - ESP_ERR_NOT_SUPPORTED: requested feature is not supported
|
||||
*/
|
||||
esp_err_t (*custom_ioctl)(esp_eth_phy_t *phy, uint32_t cmd, void *data);
|
||||
esp_err_t (*custom_ioctl)(esp_eth_phy_t *phy, int cmd, void *data);
|
||||
|
||||
/**
|
||||
* @brief Free memory of Ethernet PHY instance
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_eth.h"
|
||||
#include "esp_eth_phy.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "eth_phy_802_3_regs.h"
|
||||
|
||||
@@ -45,7 +45,7 @@ typedef enum {
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @param eth Ethernet mediator pointer
|
||||
* @return
|
||||
* - ESP_OK: Ethermet mediator set successfuly
|
||||
* - ESP_OK: Ethermet mediator set successfully
|
||||
* - ESP_ERR_INVALID_ARG: if @c eth is @c NULL
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_set_mediator(phy_802_3_t *phy_802_3, esp_eth_mediator_t *eth);
|
||||
@@ -55,8 +55,8 @@ esp_err_t esp_eth_phy_802_3_set_mediator(phy_802_3_t *phy_802_3, esp_eth_mediato
|
||||
*
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY reset successfuly
|
||||
* - ESP_FAIL: reset Ethernet PHY failed because some error occured
|
||||
* - ESP_OK: Ethernet PHY reset successfully
|
||||
* - ESP_FAIL: reset Ethernet PHY failed because some error occurred
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_reset(phy_802_3_t *phy_802_3);
|
||||
|
||||
@@ -67,8 +67,8 @@ esp_err_t esp_eth_phy_802_3_reset(phy_802_3_t *phy_802_3);
|
||||
* @param cmd autonegotiation command enumeration
|
||||
* @param[out] autonego_en_stat autonegotiation enabled flag
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY autonegotiation configured successfuly
|
||||
* - ESP_FAIL: Ethernet PHY autonegotiation configuration fail because some error occured
|
||||
* - ESP_OK: Ethernet PHY autonegotiation configured successfully
|
||||
* - ESP_FAIL: Ethernet PHY autonegotiation configuration fail because some error occurred
|
||||
* - ESP_ERR_INVALID_ARG: invalid value of @c cmd
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_autonego_ctrl(phy_802_3_t *phy_802_3, eth_phy_autoneg_cmd_t cmd, bool *autonego_en_stat);
|
||||
@@ -79,8 +79,8 @@ esp_err_t esp_eth_phy_802_3_autonego_ctrl(phy_802_3_t *phy_802_3, eth_phy_autone
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @param enable set true to power ON Ethernet PHY; set false to power OFF Ethernet PHY
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY power down mode set successfuly
|
||||
* - ESP_FAIL: Ethernet PHY power up or power down failed because some error occured
|
||||
* - ESP_OK: Ethernet PHY power down mode set successfully
|
||||
* - ESP_FAIL: Ethernet PHY power up or power down failed because some error occurred
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_pwrctl(phy_802_3_t *phy_802_3, bool enable);
|
||||
|
||||
@@ -100,7 +100,7 @@ esp_err_t esp_eth_phy_802_3_set_addr(phy_802_3_t *phy_802_3, uint32_t addr);
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @param[out] addr Ethernet PHY address
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY address read successfuly
|
||||
* - ESP_OK: Ethernet PHY address read successfully
|
||||
* - ESP_ERR_INVALID_ARG: @c addr pointer is @c NULL
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_get_addr(phy_802_3_t *phy_802_3, uint32_t *addr);
|
||||
@@ -111,8 +111,8 @@ esp_err_t esp_eth_phy_802_3_get_addr(phy_802_3_t *phy_802_3, uint32_t *addr);
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @param ability enable or disable pause ability
|
||||
* @return
|
||||
* - ESP_OK: pause ability set successfuly
|
||||
* - ESP_FAIL: Advertise pause function ability failed because some error occured
|
||||
* - ESP_OK: pause ability set successfully
|
||||
* - ESP_FAIL: Advertise pause function ability failed because some error occurred
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_advertise_pause_ability(phy_802_3_t *phy_802_3, uint32_t ability);
|
||||
|
||||
@@ -122,8 +122,8 @@ esp_err_t esp_eth_phy_802_3_advertise_pause_ability(phy_802_3_t *phy_802_3, uint
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @param enable set true to enable loopback; set false to disable loopback
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY loopback mode set successfuly
|
||||
* - ESP_FAIL: Ethernet PHY loopback configuration failed because some error occured
|
||||
* - ESP_OK: Ethernet PHY loopback mode set successfully
|
||||
* - ESP_FAIL: Ethernet PHY loopback configuration failed because some error occurred
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_loopback(phy_802_3_t *phy_802_3, bool enable);
|
||||
|
||||
@@ -133,8 +133,8 @@ esp_err_t esp_eth_phy_802_3_loopback(phy_802_3_t *phy_802_3, bool enable);
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @param speed new speed of Ethernet PHY link
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY speed set successfuly
|
||||
* - ESP_FAIL: Set Ethernet PHY speed failed because some error occured
|
||||
* - ESP_OK: Ethernet PHY speed set successfully
|
||||
* - ESP_FAIL: Set Ethernet PHY speed failed because some error occurred
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_set_speed(phy_802_3_t *phy_802_3, eth_speed_t speed);
|
||||
|
||||
@@ -144,9 +144,9 @@ esp_err_t esp_eth_phy_802_3_set_speed(phy_802_3_t *phy_802_3, eth_speed_t speed)
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @param duplex new duplex mode for Ethernet PHY link
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY duplex mode set successfuly
|
||||
* - ESP_OK: Ethernet PHY duplex mode set successfully
|
||||
* - ESP_ERR_INVALID_STATE: unable to set duplex mode to Half if loopback is enabled
|
||||
* - ESP_FAIL: Set Ethernet PHY duplex mode failed because some error occured
|
||||
* - ESP_FAIL: Set Ethernet PHY duplex mode failed because some error occurred
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_set_duplex(phy_802_3_t *phy_802_3, eth_duplex_t duplex);
|
||||
|
||||
@@ -156,7 +156,7 @@ esp_err_t esp_eth_phy_802_3_set_duplex(phy_802_3_t *phy_802_3, eth_duplex_t dupl
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @param link new link status
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY link set successfuly
|
||||
* - ESP_OK: Ethernet PHY link set successfully
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_set_link(phy_802_3_t *phy_802_3, eth_link_t link);
|
||||
|
||||
@@ -165,7 +165,7 @@ esp_err_t esp_eth_phy_802_3_set_link(phy_802_3_t *phy_802_3, eth_link_t link);
|
||||
*
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY initialized successfuly
|
||||
* - ESP_OK: Ethernet PHY initialized successfully
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_init(phy_802_3_t *phy_802_3);
|
||||
|
||||
@@ -174,7 +174,7 @@ esp_err_t esp_eth_phy_802_3_init(phy_802_3_t *phy_802_3);
|
||||
*
|
||||
* @param phy_802_3 IEEE 802.3 PHY object infostructure
|
||||
* @return
|
||||
* - ESP_OK: Ethernet PHY powered off successfuly
|
||||
* - ESP_OK: Ethernet PHY powered off successfully
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_deinit(phy_802_3_t *phy_802_3);
|
||||
|
||||
@@ -275,8 +275,8 @@ esp_err_t esp_eth_phy_802_3_read_manufac_info(phy_802_3_t *phy_802_3, uint8_t *m
|
||||
* @param devaddr Address of MDIO device
|
||||
* @param[out] mmd_addr Current address stored in device's register
|
||||
* @return
|
||||
* - ESP_OK: Address register read successfuly
|
||||
* - ESP_FAIL: Address register read failed because of some error occured
|
||||
* - ESP_OK: Address register read successfully
|
||||
* - ESP_FAIL: Address register read failed because of some error occurred
|
||||
* - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits)
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_get_mmd_addr(phy_802_3_t *phy_802_3, uint8_t devaddr, uint16_t *mmd_addr);
|
||||
@@ -288,8 +288,8 @@ esp_err_t esp_eth_phy_802_3_get_mmd_addr(phy_802_3_t *phy_802_3, uint8_t devaddr
|
||||
* @param devaddr Address of MDIO device
|
||||
* @param[out] mmd_addr New value of MDIO device's address register value
|
||||
* @return
|
||||
* - ESP_OK: Address register written to successfuly
|
||||
* - ESP_FAIL: Address register write failed because of some error occured
|
||||
* - ESP_OK: Address register written to successfully
|
||||
* - ESP_FAIL: Address register write failed because of some error occurred
|
||||
* - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits)
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_set_mmd_addr(phy_802_3_t *phy_802_3, uint8_t devaddr, uint16_t mmd_addr);
|
||||
@@ -302,8 +302,8 @@ esp_err_t esp_eth_phy_802_3_set_mmd_addr(phy_802_3_t *phy_802_3, uint8_t devaddr
|
||||
* @param function MMD function
|
||||
* @param[out] data Data read from the device's memory
|
||||
* @return
|
||||
* - ESP_OK: Memory read successfuly
|
||||
* - ESP_FAIL: Memory read failed because of some error occured
|
||||
* - ESP_OK: Memory read successfully
|
||||
* - ESP_FAIL: Memory read failed because of some error occurred
|
||||
* - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits) or MMD access function is invalid
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_read_mmd_data(phy_802_3_t *phy_802_3, uint8_t devaddr, esp_eth_phy_802_3_mmd_func_t function, uint32_t *data);
|
||||
@@ -316,8 +316,8 @@ esp_err_t esp_eth_phy_802_3_read_mmd_data(phy_802_3_t *phy_802_3, uint8_t devadd
|
||||
* @param function MMD function
|
||||
* @param[out] data Data to write to the device's memory
|
||||
* @return
|
||||
* - ESP_OK: Memory written successfuly
|
||||
* - ESP_FAIL: Memory write failed because of some error occured
|
||||
* - ESP_OK: Memory written successfully
|
||||
* - ESP_FAIL: Memory write failed because of some error occurred
|
||||
* - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits) or MMD access function is invalid
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_write_mmd_data(phy_802_3_t *phy_802_3, uint8_t devaddr, esp_eth_phy_802_3_mmd_func_t function, uint32_t data);
|
||||
@@ -330,8 +330,8 @@ esp_err_t esp_eth_phy_802_3_write_mmd_data(phy_802_3_t *phy_802_3, uint8_t devad
|
||||
* @param mmd_addr Address of MDIO device register
|
||||
* @param[out] data Data read from the device's memory
|
||||
* @return
|
||||
* - ESP_OK: Memory read successfuly
|
||||
* - ESP_FAIL: Memory read failed because of some error occured
|
||||
* - ESP_OK: Memory read successfully
|
||||
* - ESP_FAIL: Memory read failed because of some error occurred
|
||||
* - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits)
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_read_mmd_register(phy_802_3_t *phy_802_3, uint8_t devaddr, uint16_t mmd_addr, uint32_t *data);
|
||||
@@ -344,8 +344,8 @@ esp_err_t esp_eth_phy_802_3_read_mmd_register(phy_802_3_t *phy_802_3, uint8_t de
|
||||
* @param mmd_addr Address of MDIO device register
|
||||
* @param[out] data Data to write to the device's memory
|
||||
* @return
|
||||
* - ESP_OK: Memory written to successfuly
|
||||
* - ESP_FAIL: Memory write failed because of some error occured
|
||||
* - ESP_OK: Memory written to successfully
|
||||
* - ESP_FAIL: Memory write failed because of some error occurred
|
||||
* - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits)
|
||||
*/
|
||||
esp_err_t esp_eth_phy_802_3_write_mmd_register(phy_802_3_t *phy_802_3, uint8_t devaddr, uint16_t mmd_addr, uint32_t data);
|
||||
|
||||
@@ -15,20 +15,144 @@ extern "C" {
|
||||
* @brief Indicate to ::emac_esp_dma_receive_frame that receive frame buffer was allocated by ::emac_esp_dma_alloc_recv_buf
|
||||
*
|
||||
*/
|
||||
#define EMAC_HAL_BUF_SIZE_AUTO 0
|
||||
#define EMAC_DMA_BUF_SIZE_AUTO 0
|
||||
|
||||
/**
|
||||
* @brief EMAC DMA handle
|
||||
*
|
||||
*/
|
||||
typedef struct emac_esp_dma_t *emac_esp_dma_handle_t;
|
||||
|
||||
typedef void *emac_esp_dma_config_t;
|
||||
|
||||
void emac_esp_dma_reset_desc_chain(emac_esp_dma_handle_t emac_esp_dma);
|
||||
/**
|
||||
* @brief EMAC DMA configuration
|
||||
* @note Currently just a placeholder
|
||||
*
|
||||
*/
|
||||
typedef struct emac_esp_dma_config_t emac_esp_dma_config_t;
|
||||
|
||||
/**
|
||||
* @brief Reset DMA
|
||||
* @note This function should be called prior each EMAC start
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
*/
|
||||
void emac_esp_dma_reset(emac_esp_dma_handle_t emac_esp_dma);
|
||||
|
||||
/**
|
||||
* @brief Transmit data from buffer over EMAC
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
* @param[in] buf buffer to be transmitted
|
||||
* @param[in] length length of the buffer
|
||||
* @return number of transmitted bytes on success
|
||||
* zero on fail
|
||||
*/
|
||||
uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t length);
|
||||
uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t **buffs, uint32_t *lengths, uint32_t buffs_cnt);
|
||||
uint8_t *emac_esp_dma_alloc_recv_buf(emac_esp_dma_handle_t emac_esp_dma, uint32_t *size);
|
||||
uint32_t emac_esp_dma_receive_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t size, uint32_t *frames_remain, uint32_t *free_desc);
|
||||
void emac_esp_dma_flush_recv_frame(emac_esp_dma_handle_t emac_esp_dma, uint32_t *frames_remain, uint32_t *free_desc);
|
||||
|
||||
/**
|
||||
* @brief Transmit data from multiple buffers over EMAC in single Ethernet frame. Data will be joint into
|
||||
* single frame in order in which the buffers are stored in input array.
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
* @param[in] buffs array of pointers to buffers to be transmitted
|
||||
* @param[in] lengths array of lengths of the buffers
|
||||
* @param[in] inbuffs_cnt number of buffers (i.e. input arrays size)
|
||||
* @return number of transmitted bytes on success
|
||||
* zero on fail
|
||||
*
|
||||
* @pre @p lengths array must have the same size as @p buffs array and their elements need to be stored in the same
|
||||
* order, i.e. lengths[1] is a length associated with data buffer referenced at buffs[1] position.
|
||||
*/
|
||||
uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t **buffs, uint32_t *lengths, uint32_t buffs_cnt);
|
||||
|
||||
/**
|
||||
* @brief Allocate buffer with size equal to actually received Ethernet frame size.
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
* @param[in, out] size as an input defines maximum size of buffer to be allocated. As an output, indicates actual size of received
|
||||
* Ethernet frame which is waiting to be processed. Returned size may be 0 when there is no waiting valid frame.
|
||||
*
|
||||
* @note If maximum allowed size of buffer to be allocated is less than actual size of received Ethernet frame, the buffer
|
||||
* is allocated with that limit and the frame will be truncated by emac_hal_receive_frame.
|
||||
*
|
||||
* @return Pointer to allocated buffer
|
||||
* NULL when allocation fails (returned @p size is non-zero)
|
||||
* NULL when there is no waiting Ethernet frame (returned @p size is zero)
|
||||
*/
|
||||
uint8_t *emac_esp_dma_alloc_recv_buf(emac_esp_dma_handle_t emac_esp_dma, uint32_t *size);
|
||||
|
||||
/**
|
||||
* @brief Copy received Ethernet frame from EMAC DMA memory space to application.
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
* @param[in] buf buffer into which the Ethernet frame is to be copied
|
||||
* @param[in] size buffer size. When buffer was allocated by ::emac_esp_dma_alloc_recv_buf, this parameter needs to be set
|
||||
* to @c EMAC_DMA_BUF_SIZE_AUTO
|
||||
*
|
||||
* @return - number of copied bytes when success
|
||||
* - number of bytes of received Ethernet frame when maximum allowed buffer @p size is less than actual size of
|
||||
* received Ethernet frame and @p size is NOT set to @c EMAC_DMA_BUF_SIZE_AUTO
|
||||
* - 0 when there is no waiting Ethernet frame or on frame error when @p size is NOT set to @c EMAC_DMA_BUF_SIZE_AUTO
|
||||
*
|
||||
* @note When this function is called with @c EMAC_DMA_BUF_SIZE_AUTO size option (preferred), buffer needs to be
|
||||
* successfully allocated by ::emac_esp_dma_alloc_recv_buf function at first.
|
||||
* @note When this function is NOT called with @c EMAC_DMA_BUF_SIZE_AUTO size option and maximum allowed buffer @p size
|
||||
* is less than actual size of received Ethernet frame, the frame will be truncated.
|
||||
* @note FCS field is never copied
|
||||
*/
|
||||
uint32_t emac_esp_dma_receive_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Flush frame stored in Rx DMA
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
*/
|
||||
void emac_esp_dma_flush_recv_frame(emac_esp_dma_handle_t emac_esp_dma);
|
||||
|
||||
/**
|
||||
* @brief Get number of frames remaining in Rx DMA
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
* @param[out] frames_remain number of frames remaining to be processed
|
||||
* @param[out] free_desc number of free DMA Rx descriptors
|
||||
*/
|
||||
void emac_esp_dma_get_remain_frames(emac_esp_dma_handle_t emac_esp_dma, uint32_t *remain_frames, uint32_t *used_descs);
|
||||
|
||||
/**
|
||||
* @brief Set the Transmit Descriptor Word 0 (TDES0) control bits
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
* @param[in] bit_mask mask of control bits to be set
|
||||
*/
|
||||
void emac_esp_dma_set_tdes0_ctrl_bits(emac_esp_dma_handle_t emac_esp_dma, uint32_t bit_mask);
|
||||
|
||||
/**
|
||||
* @brief Clear the Transmit Descriptor Word 0 (TDES0) control bits
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
* @param[in] bit_mask mask of control bits to be cleared
|
||||
*/
|
||||
void emac_esp_dma_clear_tdes0_ctrl_bits(emac_esp_dma_handle_t emac_esp_dma, uint32_t bit_mask);
|
||||
|
||||
/**
|
||||
* @brief Creates a new instance of the ESP EMAC DMA
|
||||
*
|
||||
* @param config ESP EMAC DMA configuration
|
||||
* @param[out] ret_handle EMAC DMA handle
|
||||
* @return esp_err_t
|
||||
* ESP_OK on success
|
||||
* ESP_ERR_NO_MEM when there is not enough memory to allocate instance
|
||||
*/
|
||||
esp_err_t emac_esp_new_dma(const emac_esp_dma_config_t* config, emac_esp_dma_handle_t *ret_handle);
|
||||
|
||||
/**
|
||||
* @brief Deletes the ESP EMAC DMA instance
|
||||
*
|
||||
* @param[in] emac_esp_dma EMAC DMA handle
|
||||
* @return esp_err_t
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t emac_esp_del_dma(emac_esp_dma_handle_t emac_esp_dma);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -10,53 +10,23 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_eth_mac.h"
|
||||
#include "esp_eth_mac_esp.h"
|
||||
|
||||
/**
|
||||
* @brief EMAC SMI GPIO configuration
|
||||
*/
|
||||
typedef struct {
|
||||
int mdc_num;
|
||||
int mdio_num;
|
||||
} emac_esp_smi_gpio_config_t;
|
||||
#if CONFIG_ETH_USE_ESP32_EMAC
|
||||
|
||||
/**
|
||||
* @brief EMAC MII data interface GPIO configuration
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t tx_clk_num;
|
||||
uint8_t tx_en_num;
|
||||
uint8_t txd0_num;
|
||||
uint8_t txd1_num;
|
||||
uint8_t txd2_num;
|
||||
uint8_t txd3_num;
|
||||
uint8_t rx_clk_num;
|
||||
uint8_t rx_dv_num;
|
||||
uint8_t rxd0_num;
|
||||
uint8_t rxd1_num;
|
||||
uint8_t rxd2_num;
|
||||
uint8_t rxd3_num;
|
||||
} emac_esp_mii_gpio_config_t;
|
||||
|
||||
/**
|
||||
* @brief EMAC RMII data interface GPIO configuration
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t tx_en_num;
|
||||
uint8_t txd0_num;
|
||||
uint8_t txd1_num;
|
||||
uint8_t crs_dv_num;
|
||||
uint8_t rxd0_num;
|
||||
uint8_t rxd1_num;
|
||||
} emac_esp_rmii_gpio_config_t;
|
||||
|
||||
esp_err_t emac_esp_iomux_init_mii(emac_esp_mii_gpio_config_t *mii_gpio);
|
||||
esp_err_t emac_esp_iomux_init_rmii(emac_esp_rmii_gpio_config_t *rmii_gpio);
|
||||
esp_err_t emac_esp_gpio_matrix_init_mii(const eth_mac_mii_gpio_config_t *mii_gpio);
|
||||
esp_err_t emac_esp_iomux_init_mii(const eth_mac_mii_gpio_config_t *mii_gpio);
|
||||
esp_err_t emac_esp_iomux_init_rmii(const eth_mac_rmii_gpio_config_t *rmii_gpio);
|
||||
esp_err_t emac_esp_iomux_rmii_clk_input(int num);
|
||||
esp_err_t emac_esp_iomux_rmii_clk_ouput(int num);
|
||||
esp_err_t emac_esp_iomux_init_tx_er(int num);
|
||||
esp_err_t emac_esp_iomux_init_rx_er(int num);
|
||||
void emac_esp32_gpio_init_smi(emac_esp_smi_gpio_config_t *smi_gpio);
|
||||
esp_err_t emac_esp_iomux_rmii_init_tx_er(int num);
|
||||
esp_err_t emac_esp_iomux_rmii_init_rx_er(int num);
|
||||
esp_err_t emac_esp_iomux_mii_init_tx_er(int num);
|
||||
esp_err_t emac_esp_iomux_mii_init_rx_er(int num);
|
||||
esp_err_t emac_esp_gpio_init_smi(const emac_esp_smi_gpio_config_t *smi_gpio);
|
||||
esp_err_t emac_esp_gpio_deinit_all(void);
|
||||
|
||||
#endif // CONFIG_ETH_USE_ESP32_EMAC
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user