Skip to content

Commit 55e89ef

Browse files
committed
Added generator and loopback examples for ESP32
1 parent e4be1c4 commit 55e89ef

File tree

10 files changed

+1029
-0
lines changed

10 files changed

+1029
-0
lines changed

component.mk

+12
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,15 @@ COMPONENT_SRCDIRS := ./src \
1010
./src/proto/light \
1111
./src/proto/crc \
1212

13+
CPPFLAGS += \
14+
-DTINY_LOG_LEVEL_DEFAULT=0 \
15+
-DTINY_HDLC_DEBUG=0 \
16+
-DTINY_HD_DEBUG=0 \
17+
-DTINY_FD_DEBUG=0 \
18+
-DTINY_DEBUG=0
19+
20+
CPPFLAGS += \
21+
-DCONFIG_ENABLE_FCS32 \
22+
-DCONFIG_ENABLE_FCS16 \
23+
-DCONFIG_ENABLE_CHECKSUM \
24+
-DCONFIG_ENABLE_STATS

examples/esp32_idf/README.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## Examples for ESP32
2+
3+
This folder contains 2 examples. Please follow instructions for each example and prepare 2 boards:
4+
5+
* tinyfd_generator (Generates fixed frames, sends to remote side, and receives back)
6+
* tinyfd_loopback (Receives frames, and sends them back to sender)
7+
8+
These examples use UART1 via D4 (TX), D5 (RX) pins
9+
10+
You can use single ESP32 Dev board with PC tool.
11+
12+
## Registered full duplex speed with 2 ESP32 Dev boards over UART (115200)
13+
14+
Registered full duplex speed with 2 ESP32 Dev boards over UART (running at 115200) is logged below.
15+
So, Tiny Protocol shows high channel utilization. However, payload transfer speed cannot be very close
16+
to UART baud rate because of start/stop bits, and hdlc full duplex overhead, which usually creates overhead
17+
from 4 to 20 bytes for each payload buffer being transferred.
18+
19+
```.txt
20+
Registered TX speed: payload 76921 bps, total 113120 bps
21+
Registered RX speed: payload 76377 bps, total 112320 bps
22+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include $(IDF_PATH)/make/project.mk
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Compilation
2+
3+
Copy tinyproto ./src folder and ./component.mk file to components/tinyproto folder before compilation.
4+
5+
## Options
6+
7+
Example allows to run TinyProto in single thread and multithread modes
8+
9+
> ./tiny_loopback -p /dev/ttyS8 -t fd -w 7 -g -c 16 -r
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Copy tinyproto ./src folder and ./component.mk file to this folder
2+
and then compile example with ESP-IDF
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2020, Alexey Dynda
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
#include "freertos/FreeRTOS.h"
26+
#include "freertos/task.h"
27+
#include "driver/uart.h"
28+
#include "driver/gpio.h"
29+
#include <TinyProtocolFd.h>
30+
#include <chrono>
31+
#include <stdio.h>
32+
33+
#define TINY_MULTITHREAD
34+
#define WINDOW_SIZE (7)
35+
#define GENERATED_PACKET_SIZE (64)
36+
#define BUF_SIZE (512)
37+
38+
/* Creating protocol object is simple. Lets define 256 bytes as maximum. *
39+
* size for the packet and use 7 packets in outgoing queue. */
40+
Tiny::ProtoFdD proto( tiny_fd_buffer_size_by_mtu( 256, WINDOW_SIZE ) );
41+
42+
uint32_t s_receivedBytes = 0;
43+
uint32_t s_receivedOverheadBytes = 0;
44+
uint32_t s_sentBytes = 0;
45+
uint32_t s_sentOverheadBytes = 0;
46+
47+
void onReceive(Tiny::IPacket &pkt)
48+
{
49+
s_receivedBytes += pkt.size();
50+
s_receivedOverheadBytes += /* ESCAPE */ 2 + /* CRC16 */ 2 + /* I header */ 2 ;
51+
}
52+
53+
void onSendFrameFd(Tiny::IPacket &pkt)
54+
{
55+
s_sentBytes += pkt.size();
56+
s_sentOverheadBytes += /* ESCAPE */ 2 + /* CRC16 */ 2 + /* I header */ 2 ;
57+
}
58+
59+
#if CONFIG_FREERTOS_UNICORE
60+
#define ARDUINO_RUNNING_CORE 0
61+
#else
62+
#define ARDUINO_RUNNING_CORE 1
63+
#endif
64+
65+
#if defined(TINY_MULTITHREAD)
66+
void tx_task(void *arg)
67+
{
68+
for (;;)
69+
{
70+
proto.run_tx( 100 );
71+
}
72+
vTaskDelete( NULL );
73+
}
74+
75+
void rx_task(void *arg)
76+
{
77+
for (;;)
78+
{
79+
proto.run_rx( 100 );
80+
}
81+
vTaskDelete( NULL );
82+
}
83+
84+
#endif
85+
86+
void main_task(void *args)
87+
{
88+
uart_config_t uart_config = {
89+
.baud_rate = 115200,
90+
.data_bits = UART_DATA_8_BITS,
91+
.parity = UART_PARITY_DISABLE,
92+
.stop_bits = UART_STOP_BITS_1,
93+
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
94+
.rx_flow_ctrl_thresh = 0,
95+
.use_ref_tick = false,
96+
// .source_clk = 0, // APB
97+
};
98+
ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config));
99+
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, GPIO_NUM_4 /*TX*/, GPIO_NUM_5 /* RX */, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
100+
ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, BUF_SIZE * 2, 0, 0, NULL, 0));
101+
102+
/* Lets use 16-bit checksum as ESP32 allows that */
103+
proto.enableCrc16();
104+
/* Lets use 7 frames window for outgoing messages */
105+
proto.setWindowSize( WINDOW_SIZE );
106+
proto.setReceiveCallback( onReceive );
107+
proto.setSendCallback( onSendFrameFd );
108+
#if defined(TINY_MULTITHREAD)
109+
proto.setSendTimeout( 100 );
110+
#endif
111+
/* Redirect all protocol communication to Serial0 UART */
112+
#if defined(TINY_MULTITHREAD)
113+
proto.begin([](void *p, const void *b, int s)->int { return uart_write_bytes(UART_NUM_1, (const char *)b, s); },
114+
[](void *p, void *b, int s)->int { return uart_read_bytes(UART_NUM_1, (uint8_t *)b, s, 10); });
115+
#else
116+
proto.begin([](void *p, const void *b, int s)->int { return uart_tx_chars(UART_NUM_1, (const char *)b, s); },
117+
[](void *p, void *b, int s)->int { return uart_read_bytes(UART_NUM_1, (uint8_t *)b, s, 0); });
118+
#endif
119+
120+
#if defined(TINY_MULTITHREAD)
121+
xTaskCreate( tx_task, "tx_task", 2096, NULL, 1, NULL );
122+
xTaskCreate( rx_task, "rx_task", 2096, NULL, 1, NULL );
123+
#endif
124+
auto startTs = std::chrono::steady_clock::now();
125+
126+
Tiny::PacketD packet(GENERATED_PACKET_SIZE);
127+
packet.put("Generated frame. test in progress");
128+
129+
for(;;)
130+
{
131+
132+
if ( proto.write( packet.data(), packet.size() ) < 0 )
133+
{
134+
// fprintf( stderr, "Failed to send packet\n" );
135+
}
136+
auto ts = std::chrono::steady_clock::now();
137+
if (ts - startTs >= std::chrono::seconds(5))
138+
{
139+
startTs = ts;
140+
fprintf(stderr, ".");
141+
printf("\nRegistered TX speed: payload %u bps, total %u bps\n", (s_sentBytes) * 8 / 5,
142+
(s_sentBytes + s_sentOverheadBytes) * 10 / 5);
143+
printf("Registered RX speed: payload %u bps, total %u bps\n", (s_receivedBytes) * 8 / 5,
144+
(s_receivedBytes + s_receivedOverheadBytes) * 10 / 5);
145+
s_sentBytes = 0;
146+
s_receivedBytes = 0;
147+
s_receivedOverheadBytes = 0;
148+
s_sentOverheadBytes = 0;
149+
}
150+
#if defined(TINY_MULTITHREAD)
151+
152+
#else
153+
proto.run_rx();
154+
proto.run_tx();
155+
#endif
156+
}
157+
vTaskDelete( NULL );
158+
}
159+
160+
extern "C" void app_main(void)
161+
{
162+
xTaskCreatePinnedToCore(main_task, "mainTask", 8192, NULL, 1, NULL, ARDUINO_RUNNING_CORE);
163+
}

0 commit comments

Comments
 (0)