mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-06-25 09:21:32 +02:00
feat(eppp): Add support for transport via Ethernet link
This commit is contained in:
@ -1,3 +1,22 @@
|
||||
idf_component_register(SRCS eppp_link.c eppp_sdio_slave.c eppp_sdio_host.c
|
||||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "5.3")
|
||||
set(driver_deps esp_driver_gpio esp_driver_spi)
|
||||
else()
|
||||
set(driver_deps driver)
|
||||
endif()
|
||||
|
||||
if(CONFIG_EPPP_LINK_DEVICE_ETH)
|
||||
set(transport_src eppp_eth.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_EPPP_LINK_DEVICE_SDIO)
|
||||
set(transport_src eppp_sdio_slave.c eppp_sdio_host.c)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS eppp_link.c ${transport_src}
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES esp_netif esp_driver_spi esp_driver_gpio esp_timer driver)
|
||||
PRIV_REQUIRES esp_netif esp_timer esp_eth ${driver_deps})
|
||||
|
||||
if(CONFIG_EPPP_LINK_DEVICE_ETH)
|
||||
idf_component_get_property(ethernet_init espressif__ethernet_init COMPONENT_LIB)
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE ${ethernet_init})
|
||||
endif()
|
||||
|
@ -28,6 +28,16 @@ menu "eppp_link"
|
||||
help
|
||||
Use SDIO.
|
||||
|
||||
config EPPP_LINK_DEVICE_ETH
|
||||
bool "Ethernet"
|
||||
depends on SOC_EMAC_SUPPORTED
|
||||
help
|
||||
Use Ethernet.
|
||||
This transport could employ a full fledged Ethernet connection
|
||||
between two EPPP nodes via standard Ethernet cable.
|
||||
It could be also effectively connected directly on PCB, EMAC to EMAC,
|
||||
without any Ethernet PHY chips (using eth_dummy_phy driver).
|
||||
|
||||
endchoice
|
||||
|
||||
config EPPP_LINK_CONN_MAX_RETRY
|
||||
@ -67,4 +77,14 @@ menu "eppp_link"
|
||||
|
||||
endchoice
|
||||
|
||||
config EPPP_LINK_ETHERNET_OUR_ADDRESS
|
||||
string "MAC address our local node"
|
||||
default "06:00:00:00:00:01"
|
||||
depends on EPPP_LINK_DEVICE_ETH
|
||||
|
||||
config EPPP_LINK_ETHERNET_THEIR_ADDRESS
|
||||
string "MAC address the remote node"
|
||||
default "06:00:00:00:00:02"
|
||||
depends on EPPP_LINK_DEVICE_ETH
|
||||
|
||||
endmenu
|
||||
|
@ -11,12 +11,12 @@ We usually call this node a SLAVE microcontroller. The "HOST" microcontroller ru
|
||||
brings in the WiFi connectivity from the "SLAVE" microcontroller.
|
||||
|
||||
```
|
||||
SLAVE micro HOST micro
|
||||
\|/ +----------------+ +----------------+
|
||||
| | | serial line | |
|
||||
+---+ WiFi NAT PPPoS |=== UART / SPI / SDIO =====| PPPoS client |
|
||||
| (server)| | |
|
||||
+----------------+ +----------------+
|
||||
SLAVE micro HOST micro
|
||||
\|/ +----------------+ +----------------+
|
||||
| | | (serial) line | |
|
||||
+---+ WiFi NAT PPPoS |=== UART / SPI / SDIO / ETH ===| PPPoS client |
|
||||
| (server)| | |
|
||||
+----------------+ +----------------+
|
||||
```
|
||||
|
||||
## API
|
||||
@ -55,3 +55,9 @@ Tested with WiFi-NAPT example
|
||||
|
||||
* TCP - 9Mbits/s
|
||||
* UDP - 11Mbits/s
|
||||
|
||||
### Ethernet
|
||||
|
||||
- Internal EMAC with real PHY chip
|
||||
* TCP - 5Mbits/s
|
||||
* UDP - 8Mbits/s
|
||||
|
119
components/eppp_link/eppp_eth.c
Normal file
119
components/eppp_link/eppp_eth.c
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_mac.h"
|
||||
#include "eppp_link.h"
|
||||
#include "eppp_transport.h"
|
||||
#include "esp_eth_driver.h"
|
||||
#include "ethernet_init.h"
|
||||
#include "esp_eth_spec.h"
|
||||
|
||||
typedef struct header {
|
||||
uint8_t dst[ETH_ADDR_LEN];
|
||||
uint8_t src[ETH_ADDR_LEN];
|
||||
uint16_t len;
|
||||
} __attribute__((packed)) header_t;
|
||||
|
||||
static const char *TAG = "eppp_ethernet";
|
||||
static bool s_is_connected = false;
|
||||
static esp_eth_handle_t *s_eth_handles = NULL;
|
||||
static uint8_t s_out_buffer[ETH_MAX_PACKET_SIZE];
|
||||
static uint8_t s_their_mac[ETH_ADDR_LEN];
|
||||
static uint8_t s_our_mac[ETH_ADDR_LEN];
|
||||
|
||||
static void event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
switch (event_id) {
|
||||
case ETHERNET_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "Ethernet Link Up");
|
||||
s_is_connected = true;
|
||||
break;
|
||||
case ETHERNET_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "Ethernet Link Down");
|
||||
s_is_connected = false;
|
||||
break;
|
||||
case ETHERNET_EVENT_START:
|
||||
ESP_LOGI(TAG, "Ethernet Started");
|
||||
break;
|
||||
case ETHERNET_EVENT_STOP:
|
||||
ESP_LOGI(TAG, "Ethernet Stopped");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t receive(esp_eth_handle_t h, uint8_t *buffer, uint32_t len, void *netif)
|
||||
{
|
||||
header_t *head = (header_t *)buffer;
|
||||
size_t packet_len = head->len;
|
||||
if (len >= packet_len) {
|
||||
esp_err_t ret = esp_netif_receive(netif, buffer + ETH_HEADER_LEN, packet_len, NULL);
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
__attribute__((weak)) esp_err_t eppp_transport_ethernet_init(esp_eth_handle_t *handle_array[])
|
||||
{
|
||||
uint8_t eth_port_cnt = 0;
|
||||
ESP_RETURN_ON_ERROR(ethernet_init_all(handle_array, ð_port_cnt), TAG, "Failed to init common eth drivers");
|
||||
ESP_RETURN_ON_FALSE(eth_port_cnt == 1, ESP_ERR_INVALID_ARG, TAG, "multiple Ethernet devices detected, please init only one");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void eppp_transport_ethernet_deinit(esp_eth_handle_t *handle_array)
|
||||
{
|
||||
ethernet_deinit_all(s_eth_handles);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t eppp_transport_init(eppp_config_t *config, esp_netif_t *esp_netif)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(eppp_transport_ethernet_init(&s_eth_handles), TAG, "Failed to initialize Ethernet driver");
|
||||
ESP_RETURN_ON_ERROR(esp_eth_update_input_path(s_eth_handles[0], receive, esp_netif), TAG, "Failed to set Ethernet Rx callback");
|
||||
sscanf(CONFIG_EPPP_LINK_ETHERNET_OUR_ADDRESS, "%2" PRIu8 ":%2" PRIu8 ":%2" PRIi8 ":%2" PRIu8 ":%2" PRIu8 ":%2" PRIu8,
|
||||
&s_our_mac[0], &s_our_mac[1], &s_our_mac[2], &s_our_mac[3], &s_our_mac[4], &s_our_mac[5]);
|
||||
|
||||
sscanf(CONFIG_EPPP_LINK_ETHERNET_THEIR_ADDRESS, "%2" PRIu8 ":%2" PRIu8 ":%2" PRIi8 ":%2" PRIu8 ":%2" PRIu8 ":%2" PRIu8,
|
||||
&s_their_mac[0], &s_their_mac[1], &s_their_mac[2], &s_their_mac[3], &s_their_mac[4], &s_their_mac[5]);
|
||||
esp_eth_ioctl(s_eth_handles[0], ETH_CMD_S_MAC_ADDR, s_our_mac);
|
||||
ESP_RETURN_ON_ERROR(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL), TAG, "Failed to register Ethernet handlers");
|
||||
ESP_RETURN_ON_ERROR(esp_eth_start(s_eth_handles[0]), TAG, "Failed to start Ethernet driver");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void eppp_transport_deinit(void)
|
||||
{
|
||||
esp_eth_stop(s_eth_handles[0]);
|
||||
eppp_transport_ethernet_deinit(s_eth_handles);
|
||||
}
|
||||
|
||||
esp_err_t eppp_transport_tx(void *h, void *buffer, size_t len)
|
||||
{
|
||||
if (!s_is_connected) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
// setup Ethernet header
|
||||
header_t *head = (header_t *)s_out_buffer;
|
||||
memcpy(head->dst, s_their_mac, ETH_ADDR_LEN);
|
||||
memcpy(head->src, s_our_mac, ETH_ADDR_LEN);
|
||||
head->len = len;
|
||||
// support only payloads with len <= ETH_MAX_PAYLOAD_LEN
|
||||
if (len > ETH_MAX_PAYLOAD_LEN) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
memcpy(s_out_buffer + ETH_HEADER_LEN, buffer, len);
|
||||
return esp_eth_transmit(s_eth_handles[0], s_out_buffer, len + ETH_HEADER_LEN);
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
#include "esp_event.h"
|
||||
#include "esp_netif_ppp.h"
|
||||
#include "eppp_link.h"
|
||||
#include "esp_serial_slave_link/essl_sdio.h"
|
||||
#include "eppp_transport.h"
|
||||
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SPI
|
||||
#include "driver/spi_master.h"
|
||||
@ -24,6 +24,12 @@
|
||||
#include "driver/uart.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_EPPP_LINK_DEVICE_ETH
|
||||
#define EPPP_NEEDS_TASK 0
|
||||
#else
|
||||
#define EPPP_NEEDS_TASK 1
|
||||
#endif
|
||||
|
||||
static const int GOT_IPV4 = BIT0;
|
||||
static const int CONNECTION_FAILED = BIT1;
|
||||
#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED)
|
||||
@ -98,6 +104,8 @@ esp_err_t eppp_sdio_host_init(struct eppp_config_sdio_s *config);
|
||||
esp_err_t eppp_sdio_slave_init(void);
|
||||
void eppp_sdio_slave_deinit(void);
|
||||
void eppp_sdio_host_deinit(void);
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_ETH
|
||||
|
||||
#else
|
||||
static esp_err_t transmit(void *h, void *buffer, size_t len)
|
||||
{
|
||||
@ -224,6 +232,8 @@ static esp_netif_t *netif_init(eppp_type_t role, eppp_config_t *eppp_config)
|
||||
.handle = h,
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
.transmit = role == EPPP_CLIENT ? eppp_sdio_host_tx : eppp_sdio_slave_tx,
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_ETH
|
||||
.transmit = eppp_transport_tx,
|
||||
#else
|
||||
.transmit = transmit,
|
||||
#endif
|
||||
@ -691,6 +701,7 @@ esp_err_t eppp_perform(esp_netif_t *netif)
|
||||
|
||||
#endif // CONFIG_EPPP_LINK_DEVICE_SPI / UART
|
||||
|
||||
#if EPPP_NEEDS_TASK
|
||||
static void ppp_task(void *args)
|
||||
{
|
||||
esp_netif_t *netif = args;
|
||||
@ -699,6 +710,7 @@ static void ppp_task(void *args)
|
||||
h->exited = true;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool have_some_eppp_netif(esp_netif_t *netif, void *ctx)
|
||||
{
|
||||
@ -738,6 +750,8 @@ void eppp_deinit(esp_netif_t *netif)
|
||||
} else {
|
||||
eppp_sdio_slave_deinit();
|
||||
}
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_ETH
|
||||
eppp_transport_deinit();
|
||||
#endif
|
||||
netif_deinit(netif);
|
||||
}
|
||||
@ -781,6 +795,13 @@ esp_netif_t *eppp_init(eppp_type_t role, eppp_config_t *config)
|
||||
ESP_LOGE(TAG, "Failed to initialize SDIO %d", ret);
|
||||
return NULL;
|
||||
}
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_ETH
|
||||
esp_err_t ret = eppp_transport_init(config, netif);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to initialize SDIO %d", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
return netif;
|
||||
}
|
||||
@ -834,12 +855,13 @@ esp_netif_t *eppp_open(eppp_type_t role, eppp_config_t *config, int connect_time
|
||||
}
|
||||
|
||||
eppp_netif_start(netif);
|
||||
|
||||
#if EPPP_NEEDS_TASK
|
||||
if (xTaskCreate(ppp_task, "ppp connect", config->task.stack_size, netif, config->task.priority, NULL) != pdTRUE) {
|
||||
ESP_LOGE(TAG, "Failed to create a ppp connection task");
|
||||
eppp_deinit(netif);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
int netif_cnt = get_netif_num(netif);
|
||||
if (netif_cnt < 0) {
|
||||
eppp_close(netif);
|
||||
|
14
components/eppp_link/eppp_transport.h
Normal file
14
components/eppp_link/eppp_transport.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
esp_err_t eppp_transport_init(eppp_config_t *config, esp_netif_t *esp_netif);
|
||||
|
||||
esp_err_t eppp_transport_tx(void *h, void *buffer, size_t len);
|
||||
|
||||
esp_err_t eppp_transport_rx(esp_netif_t *netif);
|
||||
|
||||
void eppp_transport_deinit(void);
|
2
components/eppp_link/examples/host/sdkconfig.ci.eth
Normal file
2
components/eppp_link/examples/host/sdkconfig.ci.eth
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_EPPP_LINK_DEVICE_ETH=y
|
2
components/eppp_link/examples/host/sdkconfig.ci.sdio
Normal file
2
components/eppp_link/examples/host/sdkconfig.ci.sdio
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32p4"
|
||||
CONFIG_EPPP_LINK_DEVICE_SDIO=y
|
2
components/eppp_link/examples/slave/sdkconfig.ci.eth
Normal file
2
components/eppp_link/examples/slave/sdkconfig.ci.eth
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_EPPP_LINK_DEVICE_ETH=y
|
2
components/eppp_link/examples/slave/sdkconfig.ci.sdio
Normal file
2
components/eppp_link/examples/slave/sdkconfig.ci.sdio
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32c6"
|
||||
CONFIG_EPPP_LINK_DEVICE_SDIO=y
|
@ -4,3 +4,4 @@ description: The component provides a general purpose PPP connectivity, typicall
|
||||
dependencies:
|
||||
idf: '>=5.2'
|
||||
espressif/esp_serial_slave_link: "^1.1.0"
|
||||
espressif/ethernet_init: '>=0.0.7'
|
||||
|
@ -63,6 +63,7 @@ typedef enum eppp_transport {
|
||||
EPPP_TRANSPORT_UART,
|
||||
EPPP_TRANSPORT_SPI,
|
||||
EPPP_TRANSPORT_SDIO,
|
||||
EPPP_TRANSPORT_ETHERNET,
|
||||
} eppp_transport_t;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user