Files
esp-idf/components/esp_eth/include/esp_eth_mac_esp.h
T
Ondrej Kosta ed2e6735ff feat(esp_libc): refactored POSIX timers get/set functions
- Added sys/timex.h and clock_adjtime API
2026-03-31 22:32:33 +08:00

441 lines
17 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "soc/clk_tree_defs.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 Input RMII Clock from external. EMAC Clock GPIO number needs to be configured when this option is selected.
*
* @note See components/esp_hal_emac/esp32(*)/emac_periph.c for available GPIO numbers.
*
*/
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.
*
* @warning ESP32 Errata: If you want the Ethernet to work with Wi-Fi or BT, dont select ESP32 as RMII CLK output as it would result in clock instability.
* Applicable only to ESP32, other ESP32 SoCs are not affected.
*
* @note See components/esp_hal_emac/esp32(*)/emac_periph.c for available GPIO numbers.
*
*/
EMAC_CLK_OUT
} emac_rmii_clock_mode_t;
/**
* @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 */
int 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 {
emac_esp_smi_gpio_config_t smi_gpio; /*!< SMI GPIO numbers */
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
int32_t mdc_freq_hz; /*!< EMAC MDC frequency range limit, if set to 0 or a negative value, the driver will set the CSR clock range up to 2.5 MHz */
} 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_DUMP_REGS, /*!< Dump EMAC registers (debug option) */
} eth_mac_esp_io_cmd_t;
#ifdef SOC_EMAC_IEEE1588V2_SUPPORTED
/**
* @brief Configuration of PTP module
*
* @warning Time stamping is currently Experimental Feature! Be aware that API may change.
*
*/
typedef struct {
soc_periph_emac_ptp_clk_src_t clk_src; /*!< Clock source for PTP */
float clk_src_period_ns; /*!< Period of the clock source for PTP in nanoseconds*/
float required_accuracy_ns; /*!< Required accuracy for PTP in nanoseconds (must be worse than clock source for PTP)*/
eth_mac_ptp_roll_type_t roll_type; /*!< Rollover mode (digital or binary) for subseconds register */
} eth_mac_ptp_config_t;
/**
* @brief Type of callback function invoked under Time Stamp target time exceeded interrupt
*
* @warning Time stamping is currently Experimental Feature! Be aware that API may change.
*
* @param eth: mediator of Ethernet driver
* @param user_args user specific arguments (placeholder - IDF-11429)
*
* @return
* - TRUE when high priority task has been woken by this function
* - FALSE no high priority task was woken by this function
*/
typedef bool (*ts_target_exceed_cb_from_isr_t)(esp_eth_mediator_t *eth, void *user_args);
/**
* @brief Default configuration for PTP module
*
*/
#define ETH_MAC_ESP_PTP_DEFAULT_CONFIG() \
{ \
.clk_src = EMAC_PTP_CLK_SRC_XTAL, \
.clk_src_period_ns = 25, \
.required_accuracy_ns = 40, \
.roll_type = ETH_PTP_BINARY_ROLLOVER, \
}
#endif // SOC_EMAC_IEEE1588V2_SUPPORTED
/**
* @brief Default ESP32's EMAC specific configuration
*
*/
#if CONFIG_IDF_TARGET_ESP32
#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \
{ \
.smi_gpio = \
{ \
.mdc_num = 23, \
.mdio_num = 18 \
}, \
.interface = EMAC_DATA_INTERFACE_RMII, \
.clock_config = \
{ \
.rmii = \
{ \
.clock_mode = EMAC_CLK_EXT_IN, \
.clock_gpio = 0 \
} \
}, \
.dma_burst_len = ETH_DMA_BURST_LEN_32, \
.intr_priority = 0, \
.mdc_freq_hz = 0, \
}
#elif CONFIG_IDF_TARGET_ESP32P4
#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \
{ \
.smi_gpio = \
{ \
.mdc_num = 31, \
.mdio_num = 52 \
}, \
.interface = EMAC_DATA_INTERFACE_RMII, \
.clock_config = \
{ \
.rmii = \
{ \
.clock_mode = EMAC_CLK_EXT_IN, \
.clock_gpio = 50 \
} \
}, \
.dma_burst_len = ETH_DMA_BURST_LEN_32, \
.intr_priority = 0, \
.mdc_freq_hz = 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 \
} \
}, \
.clock_config_out_in = \
{ \
.rmii = \
{ \
.clock_mode = EMAC_CLK_EXT_IN, \
.clock_gpio = -1 \
} \
}, \
}
#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);
#ifdef SOC_EMAC_IEEE1588V2_SUPPORTED
/**
* @brief Enable/Disable PTP module
*
* @param mac: Ethernet MAC instance
* @param config: PTP configuration
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_ptp_enable(esp_eth_mac_t *mac, const eth_mac_ptp_config_t *config);
/**
* @brief Disable PTP module
*
* @param mac: Ethernet MAC instance
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_ptp_disable(esp_eth_mac_t *mac);
/**
* @brief Set PTP time
*
* @param mac: Ethernet MAC instance
* @param time: PTP time
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_set_ptp_time(esp_eth_mac_t *mac, const eth_mac_time_t *time);
/**
* @brief Get PTP time
*
* @param mac: Ethernet MAC instance
* @param time: PTP time
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_get_ptp_time(esp_eth_mac_t *mac, eth_mac_time_t *time);
/**
* @brief Adjust PTP time frequency increment by scale factor
*
* @param mac: Ethernet MAC instance
* @param scale_factor: frequency scale factor
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_adj_ptp_freq(esp_eth_mac_t *mac, double scale_factor);
/**
* @brief Adjust base PTP time frequency increment by PPS
*
* @param mac: Ethernet MAC instance
* @param adj_ppb: adjustment in ppb
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_adj_ptp_time(esp_eth_mac_t *mac, int32_t adj_ppb);
/**
* @brief Adjust PTP frequency relative to its current addend value by ppb
*
* Unlike esp_eth_mac_adj_ptp_time (absolute from base) or esp_eth_mac_adj_ptp_freq
* (relative by double scale factor), this adjusts the current addend by ppb:
* addend_new = current * (1 + adj_ppb / 10^9). Calling with adj_ppb=0 is a no-op.
*
* @param mac: Ethernet MAC instance
* @param adj_ppb: relative frequency adjustment in parts per billion
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_adj_ptp_freq_ppb(esp_eth_mac_t *mac, int32_t adj_ppb);
/**
* @brief Set Target Time at which interrupt is invoked when PTP time exceeds this value
*
* @param mac: Ethernet MAC instance
* @param target: target time
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_set_target_time(esp_eth_mac_t *mac, const eth_mac_time_t *target);
/**
* @brief Set pointer to a callback function invoked when PTP time exceeds Target Time
*
* @param mac: Ethernet MAC instance
* @param cb: callback function
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_set_target_time_cb(esp_eth_mac_t *mac, ts_target_exceed_cb_from_isr_t cb);
/**
* @brief Enable timestamp for all received frames
*
* @param mac: Ethernet MAC instance
* @param enable: enable or disable
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_enable_ts4all(esp_eth_mac_t *mac, bool enable);
/**
* @brief Set PPS0 output at GPIO
*
* @param mac: Ethernet MAC instance
* @param gpio_num: GPIO number
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_set_pps_out_gpio(esp_eth_mac_t *mac, int gpio_num);
/**
* @brief Set PPS0 output frequency
*
* @param mac: Ethernet MAC instance
* @param freq_hz: Supported frequencies: 0 = 1PPS (narrow pulse), other values generate square clock signal.
* The clock frequency must be power of two and less than or equal to 16384 Hz.
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: invalid argument
* - ESP_FAIL: failure
*/
esp_err_t esp_eth_mac_set_pps_out_freq(esp_eth_mac_t *mac, uint32_t freq_hz);
/**
* @brief Get PTP timestamp resolution
*
* @param mac: Ethernet MAC instance
*
* @return
* - PTP timestamp resolution in nanoseconds
*/
uint32_t esp_eth_mac_get_ts_resolution(esp_eth_mac_t *mac);
#endif // SOC_EMAC_IEEE1588V2_SUPPORTED
#endif // CONFIG_ETH_USE_ESP32_EMAC
#ifdef __cplusplus
}
#endif