1616#include "esp_eth_driver.h"
1717#include "ethernet_init.h"
1818#include "esp_eth_spec.h"
19+ #include "driver/gpio.h"
20+ #include "esp_eth_phy_dummy.h"
1921
2022typedef struct header {
2123 uint8_t dst [ETH_ADDR_LEN ];
@@ -65,30 +67,23 @@ static esp_err_t receive(esp_eth_handle_t h, uint8_t *buffer, uint32_t len, void
6567 return ESP_FAIL ;
6668}
6769
70+ static esp_err_t eth_init (void );
71+
6872esp_err_t eppp_transport_init (eppp_config_t * config , esp_netif_t * esp_netif )
6973{
70- uint8_t eth_port_cnt = 0 ;
71- ESP_ERROR_CHECK (ethernet_init_all (& s_eth_handles , & eth_port_cnt ));
72- if (eth_port_cnt > 1 ) {
73- ESP_LOGW (TAG , "multiple Ethernet devices detected, the first initialized is to be used!" );
74- }
75- ESP_ERROR_CHECK (esp_eth_update_input_path (s_eth_handles [0 ], receive , esp_netif ));
74+ ESP_RETURN_ON_ERROR (eth_init (), TAG , "Failed to initialize Ethernet driver" );
75+ ESP_RETURN_ON_ERROR (esp_eth_update_input_path (s_eth_handles [0 ], receive , esp_netif ), TAG , "Failed to set Ethernet Rx callback" );
7676 sscanf (CONFIG_EPPP_LINK_ETHERNET_OUR_ADDRESS , "%2" PRIu8 ":%2" PRIu8 ":%2" PRIi8 ":%2" PRIu8 ":%2" PRIu8 ":%2" PRIu8 ,
7777 & s_our_mac [0 ], & s_our_mac [1 ], & s_our_mac [2 ], & s_our_mac [3 ], & s_our_mac [4 ], & s_our_mac [5 ]);
7878
7979 sscanf (CONFIG_EPPP_LINK_ETHERNET_THEIR_ADDRESS , "%2" PRIu8 ":%2" PRIu8 ":%2" PRIi8 ":%2" PRIu8 ":%2" PRIu8 ":%2" PRIu8 ,
8080 & s_their_mac [0 ], & s_their_mac [1 ], & s_their_mac [2 ], & s_their_mac [3 ], & s_their_mac [4 ], & s_their_mac [5 ]);
8181 esp_eth_ioctl (s_eth_handles [0 ], ETH_CMD_S_MAC_ADDR , s_our_mac );
82- ESP_ERROR_CHECK (esp_event_handler_register (ETH_EVENT , ESP_EVENT_ANY_ID , event_handler , NULL ));
83- ESP_ERROR_CHECK (esp_eth_start (s_eth_handles [0 ]));
82+ ESP_RETURN_ON_ERROR (esp_event_handler_register (ETH_EVENT , ESP_EVENT_ANY_ID , event_handler , NULL ), TAG , "Failed to register Ethernet handlers" );
83+ ESP_RETURN_ON_ERROR (esp_eth_start (s_eth_handles [0 ]), TAG , "Failed to start Ethernet driver" );
8484 return ESP_OK ;
8585}
8686
87- void eppp_transport_deinit (void )
88- {
89- ethernet_deinit_all (s_eth_handles );
90- }
91-
9287esp_err_t eppp_transport_tx (void * h , void * buffer , size_t len )
9388{
9489 if (!s_is_connected ) {
@@ -107,3 +102,148 @@ esp_err_t eppp_transport_tx(void *h, void *buffer, size_t len)
107102 memcpy (s_out_buffer + ETH_HEADER_LEN , buffer , len );
108103 return esp_eth_transmit (s_eth_handles [0 ], s_out_buffer , frame_payload_len + ETH_HEADER_LEN );
109104}
105+
106+ #ifdef CONFIG_EPPP_LINK_ETHERNET_USE_DUMMY_PHY
107+
108+ static esp_eth_mac_t * s_mac = NULL ;
109+ static esp_eth_phy_t * s_phy = NULL ;
110+
111+ #if CONFIG_EPPP_LINK_ETHERNET_CLK_SOURCE
112+ IRAM_ATTR static void gpio_isr_handler (void * arg )
113+ {
114+ BaseType_t high_task_wakeup = pdFALSE ;
115+ TaskHandle_t task_handle = (TaskHandle_t )arg ;
116+
117+ vTaskNotifyGiveFromISR (task_handle , & high_task_wakeup );
118+ if (high_task_wakeup != pdFALSE ) {
119+ portYIELD_FROM_ISR ();
120+ }
121+ }
122+ #else
123+ #define STARTUP_DELAY_MS 500
124+ #endif
125+
126+ static esp_err_t eth_init (void )
127+ {
128+ #if CONFIG_EPPP_LINK_ETHERNET_CLK_SOURCE
129+ esp_rom_gpio_pad_select_gpio (EMAC_CLK_OUT_180_GPIO );
130+ gpio_set_pull_mode (EMAC_CLK_OUT_180_GPIO , GPIO_FLOATING ); // to not affect GPIO0 (so the Sink Device could be flashed)
131+ gpio_install_isr_service (0 );
132+ gpio_config_t gpio_source_cfg = {
133+ .pin_bit_mask = (1ULL << CONFIG_EPPP_LINK_ETHERNET_SINK_READY_GPIO ),
134+ .mode = GPIO_MODE_INPUT ,
135+ .pull_up_en = GPIO_PULLUP_DISABLE ,
136+ .pull_down_en = GPIO_PULLDOWN_ENABLE ,
137+ .intr_type = GPIO_INTR_ANYEDGE
138+ };
139+ gpio_config (& gpio_source_cfg );
140+ TaskHandle_t task_handle = xTaskGetHandle (pcTaskGetName (NULL ));
141+ gpio_isr_handler_add (CONFIG_EPPP_LINK_ETHERNET_SINK_READY_GPIO , gpio_isr_handler , task_handle );
142+ ESP_LOGW (TAG , "waiting for RMII CLK sink device interrupt" );
143+ ESP_LOGW (TAG , "if RMII CLK sink device is already running, reset it by `EN` button" );
144+ while (1 ) {
145+ ulTaskNotifyTake (pdTRUE , portMAX_DELAY );
146+ if (gpio_get_level (CONFIG_EPPP_LINK_ETHERNET_SINK_READY_GPIO ) == 1 ) {
147+ break ;
148+ }
149+ }
150+ ESP_LOGI (TAG , "starting Ethernet initialization" );
151+ #else
152+ gpio_config_t gpio_sink_cfg = {
153+ .pin_bit_mask = (1ULL << CONFIG_EPPP_LINK_ETHERNET_SINK_READY_GPIO ),
154+ .mode = GPIO_MODE_OUTPUT ,
155+ .pull_up_en = GPIO_PULLUP_DISABLE ,
156+ .pull_down_en = GPIO_PULLDOWN_DISABLE ,
157+ .intr_type = GPIO_INTR_DISABLE
158+ };
159+ gpio_config (& gpio_sink_cfg );
160+ gpio_set_level (CONFIG_EPPP_LINK_ETHERNET_SINK_READY_GPIO , 0 );
161+ vTaskDelay (pdMS_TO_TICKS (STARTUP_DELAY_MS ));
162+ gpio_set_level (CONFIG_EPPP_LINK_ETHERNET_SINK_READY_GPIO , 1 );
163+ #endif // CONFIG_EPPP_LINK_ETHERNET_CLK_SOURCE
164+
165+ // --- Initialize Ethernet driver ---
166+ // Init common MAC and PHY configs to default
167+ eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG ();
168+ eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG ();
169+
170+ // Update PHY config based on board specific configuration
171+ phy_config .reset_gpio_num = -1 ; // no HW reset
172+
173+ // Init vendor specific MAC config to default
174+ eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG ();
175+ // Update vendor specific MAC config based on board configuration
176+ // No SMI, speed/duplex must be statically configured the same in both devices
177+ #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL (5 , 3 , 0 )
178+ esp32_emac_config .smi_gpio .mdc_num = -1 ;
179+ esp32_emac_config .smi_gpio .mdio_num = -1 ;
180+ #else
181+ esp32_emac_config .smi_mdc_gpio_num = -1 ;
182+ esp32_emac_config .smi_mdio_gpio_num = -1 ;
183+ #endif
184+ #if CONFIG_EPPP_LINK_ETHERNET_CLK_SOURCE
185+ esp32_emac_config .clock_config .rmii .clock_mode = EMAC_CLK_OUT ;
186+ esp32_emac_config .clock_config .rmii .clock_gpio = EMAC_CLK_OUT_180_GPIO ;
187+ #else
188+ esp32_emac_config .clock_config .rmii .clock_mode = EMAC_CLK_EXT_IN ;
189+ esp32_emac_config .clock_config .rmii .clock_gpio = EMAC_CLK_IN_GPIO ;
190+ #endif // CONFIG_EPPP_LINK_ETHERNET_CLK_SOURCE
191+
192+ // Create new ESP32 Ethernet MAC instance
193+ s_mac = esp_eth_mac_new_esp32 (& esp32_emac_config , & mac_config );
194+ // Create dummy PHY instance
195+ s_phy = esp_eth_phy_new_dummy (& phy_config );
196+
197+ // Init Ethernet driver to default and install it
198+ s_eth_handles = malloc (sizeof (esp_eth_handle_t ));
199+ ESP_RETURN_ON_FALSE (s_eth_handles , ESP_ERR_NO_MEM , TAG , "Our of memory" );
200+ esp_eth_config_t config = ETH_DEFAULT_CONFIG (s_mac , s_phy );
201+ #if CONFIG_EPPP_LINK_ETHERNET_CLK_SINK
202+ // REF RMII CLK sink device performs multiple EMAC init attempts since RMII CLK source device may not be ready yet
203+ int i ;
204+ for (i = 1 ; i <= 5 ; i ++ ) {
205+ ESP_LOGI (TAG , "Ethernet driver install attempt: %i" , i );
206+ if (esp_eth_driver_install (& config , & s_eth_handles [0 ]) == ESP_OK ) {
207+ break ;
208+ }
209+ vTaskDelay (pdMS_TO_TICKS (100 ));
210+ }
211+ ESP_RETURN_ON_FALSE (i <= 5 , ESP_FAIL , TAG , "Ethernet driver install failed" );
212+ #else
213+ ESP_RETURN_ON_ERROR (esp_eth_driver_install (& config , & s_eth_handles [0 ]), TAG , "Ethernet driver install failed" );
214+ #endif // CONFIG_EPPP_LINK_ETHERNET_CLK_SINK
215+ return ESP_OK ;
216+ }
217+
218+ void eppp_transport_deinit (void )
219+ {
220+ if (esp_eth_driver_uninstall (& s_eth_handles [0 ]) != ESP_OK ) {
221+ ESP_LOGE (TAG , "Unable to deinitialize ethernet handle" );
222+ }
223+ if (s_mac ) {
224+ s_mac -> del (s_mac );
225+ s_mac = NULL ;
226+ }
227+ if (s_phy ) {
228+ s_phy -> del (s_phy );
229+ s_phy = NULL ;
230+ }
231+ free (s_eth_handles );
232+ s_eth_handles = NULL ;
233+ }
234+
235+ #else
236+ static esp_err_t eth_init (void )
237+ {
238+ uint8_t eth_port_cnt = 0 ;
239+ ESP_RETURN_ON_ERROR (ethernet_init_all (& s_eth_handles , & eth_port_cnt ), TAG , "Failed to init common eth drivers" );
240+ ESP_RETURN_ON_FALSE (eth_port_cnt > 1 , ESP_ERR_INVALID_ARG , TAG , "multiple Ethernet devices detected, please init only one" );
241+ return ESP_OK ;
242+ }
243+
244+ void eppp_transport_deinit (void )
245+ {
246+ ethernet_deinit_all (s_eth_handles );
247+ }
248+
249+ #endif // CONFIG_EPPP_LINK_ETHERNET_USE_DUMMY_PHY
0 commit comments