Skip to content

Commit 776e40c

Browse files
committed
feat(eppp): Add support for transport via Ethernet link
1 parent 5964ead commit 776e40c

11 files changed

+203
-10
lines changed

components/eppp_link/CMakeLists.txt

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1-
idf_component_register(SRCS eppp_link.c eppp_sdio_slave.c eppp_sdio_host.c
1+
if(CONFIG_EPPP_LINK_DEVICE_ETH)
2+
set(transport_src eppp_eth.c)
3+
endif()
4+
5+
if(CONFIG_EPPP_LINK_DEVICE_SDIO)
6+
set(transport_src eppp_sdio_slave.c eppp_sdio_host.c)
7+
endif()
8+
9+
idf_component_register(SRCS eppp_link.c ${transport_src}
210
INCLUDE_DIRS "include"
3-
PRIV_REQUIRES esp_netif esp_driver_spi esp_driver_gpio esp_timer driver)
11+
PRIV_REQUIRES esp_netif esp_driver_spi esp_driver_gpio esp_timer driver esp_eth)
12+
13+
if(CONFIG_EPPP_LINK_DEVICE_ETH)
14+
idf_component_get_property(ethernet_init espressif__ethernet_init COMPONENT_LIB)
15+
target_link_libraries(${COMPONENT_LIB} PRIVATE ${ethernet_init})
16+
endif()

components/eppp_link/Kconfig

+20
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ menu "eppp_link"
2828
help
2929
Use SDIO.
3030

31+
config EPPP_LINK_DEVICE_ETH
32+
bool "Ethernet"
33+
depends on SOC_EMAC_SUPPORTED
34+
help
35+
Use Ethernet.
36+
This transport could employ a full fledged Ethernet connection
37+
between two EPPP nodes via standard Ethernet cable.
38+
It could be also effectively connected directly on PCB, EMAC to EMAC,
39+
without any Ethernet PHY chips (using eth_dummy_phy driver).
40+
3141
endchoice
3242

3343
config EPPP_LINK_CONN_MAX_RETRY
@@ -67,4 +77,14 @@ menu "eppp_link"
6777

6878
endchoice
6979

80+
config EPPP_LINK_ETHERNET_OUR_ADDRESS
81+
string "MAC address our local node"
82+
default "06:00:00:00:00:01"
83+
depends on EPPP_LINK_DEVICE_ETH
84+
85+
config EPPP_LINK_ETHERNET_THEIR_ADDRESS
86+
string "MAC address the remote node"
87+
default "06:00:00:00:00:02"
88+
depends on EPPP_LINK_DEVICE_ETH
89+
7090
endmenu

components/eppp_link/README.md

+12-6
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ We usually call this node a SLAVE microcontroller. The "HOST" microcontroller ru
1111
brings in the WiFi connectivity from the "SLAVE" microcontroller.
1212

1313
```
14-
SLAVE micro HOST micro
15-
\|/ +----------------+ +----------------+
16-
| | | serial line | |
17-
+---+ WiFi NAT PPPoS |=== UART / SPI / SDIO =====| PPPoS client |
18-
| (server)| | |
19-
+----------------+ +----------------+
14+
SLAVE micro HOST micro
15+
\|/ +----------------+ +----------------+
16+
| | | (serial) line | |
17+
+---+ WiFi NAT PPPoS |=== UART / SPI / SDIO / ETH ===| PPPoS client |
18+
| (server)| | |
19+
+----------------+ +----------------+
2020
```
2121

2222
## API
@@ -55,3 +55,9 @@ Tested with WiFi-NAPT example
5555

5656
* TCP - 9Mbits/s
5757
* UDP - 11Mbits/s
58+
59+
### Ethernet
60+
61+
- Internal EMAC with real PHY chip
62+
* TCP - 5Mbits/s
63+
* UDP - 8Mbits/s

components/eppp_link/eppp_eth.c

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <string.h>
7+
#include <stdint.h>
8+
#include <inttypes.h>
9+
#include "esp_log.h"
10+
#include "esp_netif.h"
11+
#include "esp_check.h"
12+
#include "esp_event.h"
13+
#include "esp_mac.h"
14+
#include "eppp_link.h"
15+
#include "eppp_transport.h"
16+
#include "esp_eth_driver.h"
17+
#include "ethernet_init.h"
18+
#include "esp_eth_spec.h"
19+
20+
typedef struct header {
21+
uint8_t dst[ETH_ADDR_LEN];
22+
uint8_t src[ETH_ADDR_LEN];
23+
uint16_t len;
24+
} __attribute__((packed)) header_t;
25+
26+
static const char *TAG = "eppp_ethernet";
27+
static bool s_is_connected = false;
28+
static esp_eth_handle_t *s_eth_handles = NULL;
29+
static uint8_t s_out_buffer[ETH_MAX_PACKET_SIZE];
30+
static uint8_t s_their_mac[ETH_ADDR_LEN];
31+
static uint8_t s_our_mac[ETH_ADDR_LEN];
32+
33+
static void event_handler(void *arg, esp_event_base_t event_base,
34+
int32_t event_id, void *event_data)
35+
{
36+
switch (event_id) {
37+
case ETHERNET_EVENT_CONNECTED:
38+
ESP_LOGI(TAG, "Ethernet Link Up");
39+
s_is_connected = true;
40+
break;
41+
case ETHERNET_EVENT_DISCONNECTED:
42+
ESP_LOGI(TAG, "Ethernet Link Down");
43+
s_is_connected = false;
44+
break;
45+
case ETHERNET_EVENT_START:
46+
ESP_LOGI(TAG, "Ethernet Started");
47+
break;
48+
case ETHERNET_EVENT_STOP:
49+
ESP_LOGI(TAG, "Ethernet Stopped");
50+
break;
51+
default:
52+
break;
53+
}
54+
}
55+
56+
static esp_err_t receive(esp_eth_handle_t h, uint8_t *buffer, uint32_t len, void *netif)
57+
{
58+
header_t *head = (header_t *)buffer;
59+
size_t packet_len = head->len;
60+
if (len >= packet_len) {
61+
esp_err_t ret = esp_netif_receive(netif, buffer + ETH_HEADER_LEN, packet_len, NULL);
62+
free(buffer);
63+
return ret;
64+
}
65+
return ESP_FAIL;
66+
}
67+
68+
esp_err_t eppp_transport_init(eppp_config_t *config, esp_netif_t *esp_netif)
69+
{
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));
76+
sscanf(CONFIG_EPPP_LINK_ETHERNET_OUR_ADDRESS, "%2" PRIu8 ":%2" PRIu8 ":%2" PRIi8 ":%2" PRIu8 ":%2" PRIu8 ":%2" PRIu8,
77+
&s_our_mac[0], &s_our_mac[1], &s_our_mac[2], &s_our_mac[3], &s_our_mac[4], &s_our_mac[5]);
78+
79+
sscanf(CONFIG_EPPP_LINK_ETHERNET_THEIR_ADDRESS, "%2" PRIu8 ":%2" PRIu8 ":%2" PRIi8 ":%2" PRIu8 ":%2" PRIu8 ":%2" PRIu8,
80+
&s_their_mac[0], &s_their_mac[1], &s_their_mac[2], &s_their_mac[3], &s_their_mac[4], &s_their_mac[5]);
81+
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]));
84+
return ESP_OK;
85+
}
86+
87+
void eppp_transport_deinit(void)
88+
{
89+
ethernet_deinit_all(s_eth_handles);
90+
}
91+
92+
esp_err_t eppp_transport_tx(void *h, void *buffer, size_t len)
93+
{
94+
if (!s_is_connected) {
95+
return ESP_OK;
96+
}
97+
// setup Ethernet header
98+
header_t *head = (header_t *)s_out_buffer;
99+
memcpy(head->dst, s_their_mac, ETH_ADDR_LEN);
100+
memcpy(head->src, s_our_mac, ETH_ADDR_LEN);
101+
head->len = len;
102+
// handle frame size: ETH_MIN_PAYLOAD_LEN <= len <= ETH_MAX_PAYLOAD_LEN
103+
size_t frame_payload_len = len < ETH_MIN_PAYLOAD_LEN ? ETH_MIN_PAYLOAD_LEN : len;
104+
if (frame_payload_len > ETH_MAX_PAYLOAD_LEN) {
105+
return ESP_FAIL;
106+
}
107+
memcpy(s_out_buffer + ETH_HEADER_LEN, buffer, len);
108+
return esp_eth_transmit(s_eth_handles[0], s_out_buffer, frame_payload_len + ETH_HEADER_LEN);
109+
}

components/eppp_link/eppp_link.c

+24-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "esp_event.h"
1313
#include "esp_netif_ppp.h"
1414
#include "eppp_link.h"
15-
#include "esp_serial_slave_link/essl_sdio.h"
15+
#include "eppp_transport.h"
1616

1717
#if CONFIG_EPPP_LINK_DEVICE_SPI
1818
#include "driver/spi_master.h"
@@ -24,6 +24,12 @@
2424
#include "driver/uart.h"
2525
#endif
2626

27+
#if CONFIG_EPPP_LINK_DEVICE_ETH
28+
#define EPPP_NEEDS_TASK 0
29+
#else
30+
#define EPPP_NEEDS_TASK 1
31+
#endif
32+
2733
static const int GOT_IPV4 = BIT0;
2834
static const int CONNECTION_FAILED = BIT1;
2935
#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED)
@@ -98,6 +104,8 @@ esp_err_t eppp_sdio_host_init(struct eppp_config_sdio_s *config);
98104
esp_err_t eppp_sdio_slave_init(void);
99105
void eppp_sdio_slave_deinit(void);
100106
void eppp_sdio_host_deinit(void);
107+
#elif CONFIG_EPPP_LINK_DEVICE_ETH
108+
101109
#else
102110
static esp_err_t transmit(void *h, void *buffer, size_t len)
103111
{
@@ -224,6 +232,8 @@ static esp_netif_t *netif_init(eppp_type_t role, eppp_config_t *eppp_config)
224232
.handle = h,
225233
#if CONFIG_EPPP_LINK_DEVICE_SDIO
226234
.transmit = role == EPPP_CLIENT ? eppp_sdio_host_tx : eppp_sdio_slave_tx,
235+
#elif CONFIG_EPPP_LINK_DEVICE_ETH
236+
.transmit = eppp_transport_tx,
227237
#else
228238
.transmit = transmit,
229239
#endif
@@ -691,6 +701,7 @@ esp_err_t eppp_perform(esp_netif_t *netif)
691701

692702
#endif // CONFIG_EPPP_LINK_DEVICE_SPI / UART
693703

704+
#if EPPP_NEEDS_TASK
694705
static void ppp_task(void *args)
695706
{
696707
esp_netif_t *netif = args;
@@ -699,6 +710,7 @@ static void ppp_task(void *args)
699710
h->exited = true;
700711
vTaskDelete(NULL);
701712
}
713+
#endif
702714

703715
static bool have_some_eppp_netif(esp_netif_t *netif, void *ctx)
704716
{
@@ -738,6 +750,8 @@ void eppp_deinit(esp_netif_t *netif)
738750
} else {
739751
eppp_sdio_slave_deinit();
740752
}
753+
#elif CONFIG_EPPP_LINK_DEVICE_ETH
754+
eppp_transport_deinit();
741755
#endif
742756
netif_deinit(netif);
743757
}
@@ -781,6 +795,13 @@ esp_netif_t *eppp_init(eppp_type_t role, eppp_config_t *config)
781795
ESP_LOGE(TAG, "Failed to initialize SDIO %d", ret);
782796
return NULL;
783797
}
798+
#elif CONFIG_EPPP_LINK_DEVICE_ETH
799+
esp_err_t ret = eppp_transport_init(config, netif);
800+
if (ret != ESP_OK) {
801+
ESP_LOGE(TAG, "Failed to initialize SDIO %d", ret);
802+
return NULL;
803+
}
804+
784805
#endif
785806
return netif;
786807
}
@@ -834,12 +855,13 @@ esp_netif_t *eppp_open(eppp_type_t role, eppp_config_t *config, int connect_time
834855
}
835856

836857
eppp_netif_start(netif);
837-
858+
#if EPPP_NEEDS_TASK
838859
if (xTaskCreate(ppp_task, "ppp connect", config->task.stack_size, netif, config->task.priority, NULL) != pdTRUE) {
839860
ESP_LOGE(TAG, "Failed to create a ppp connection task");
840861
eppp_deinit(netif);
841862
return NULL;
842863
}
864+
#endif
843865
int netif_cnt = get_netif_num(netif);
844866
if (netif_cnt < 0) {
845867
eppp_close(netif);

components/eppp_link/eppp_transport.h

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#pragma once
7+
8+
esp_err_t eppp_transport_init(eppp_config_t *config, esp_netif_t *esp_netif);
9+
10+
esp_err_t eppp_transport_tx(void *h, void *buffer, size_t len);
11+
12+
esp_err_t eppp_transport_rx(esp_netif_t *netif);
13+
14+
void eppp_transport_deinit(void);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_IDF_TARGET="esp32"
2+
CONFIG_EPPP_LINK_DEVICE_ETH=y
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_IDF_TARGET="esp32p4"
2+
CONFIG_EPPP_LINK_DEVICE_SDIO=y
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_IDF_TARGET="esp32"
2+
CONFIG_EPPP_LINK_DEVICE_ETH=y
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_IDF_TARGET="esp32c6"
2+
CONFIG_EPPP_LINK_DEVICE_SDIO=y

components/eppp_link/idf_component.yml

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ description: The component provides a general purpose PPP connectivity, typicall
44
dependencies:
55
idf: '>=5.2'
66
espressif/esp_serial_slave_link: "^1.1.0"
7+
espressif/ethernet_init: '>=0.0.7'

0 commit comments

Comments
 (0)