Skip to content

Commit b781195

Browse files
Fix USB-CDC custom transport example (#360)
Co-authored-by: Mohamed-Sejid <sejidmrad@gmail.com>
1 parent fc2749c commit b781195

14 files changed

Lines changed: 99 additions & 86 deletions

File tree

‎.gitignore‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ micro_ros_dev
22
micro_ros_src
33
esp32_toolchain.cmake
44
*.a
5-
include
5+
include
6+
dependencies.lock

‎examples/int32_publisher_custom_transport_usbcdc/README.md‎

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@ This example is configured to use the two interfaces of USB-CDC. One interface i
1616

1717
### Hardware Required
1818

19-
This example can be run on any development board that has a USB-CDC interface.
19+
This example can be run on any ESP32-S2 or ESP32-S3 development board that exposes the chip's native USB interface.
20+
21+
Some development boards have two USB connectors:
22+
23+
- A USB-to-UART connector, which is commonly used for flashing and serial monitor.
24+
- A native USB connector wired directly to the ESP32-S2/S3 USB pins.
25+
26+
This example uses the native USB connector at runtime. The application exposes USB-CDC ACM interfaces from the ESP32-S2/S3 itself, so the micro-ROS Agent must be connected to the native USB connector, not to the USB-to-UART connector.
2027

2128
### Configure the project
2229

@@ -31,37 +38,63 @@ If you want to use only the micro-ROS communication interface, you need to turn
3138
### Build and Flash
3239

3340
> [!NOTE]
34-
> The ESP32-S2/S3 chip needs to be in bootloader mode before it can be detected as a DFU device and flash. This can be achieved by pulling GPIO0 down (e.g., pressing the BOOT button), pulling RESET down for a moment, and releasing GPIO0.
41+
> You can flash the firmware through any supported ESP-IDF flashing interface. If you flash through a USB-to-UART connector, reconnect the board through the native USB connector before running the micro-ROS Agent.
3542
3643
#### Build the project
3744

38-
Build DFU image:
45+
```bash
46+
idf.py build
47+
```
48+
49+
#### Flash using USB-to-UART
50+
51+
If your board has a USB-to-UART connector, you can flash the application with the regular ESP-IDF serial flashing flow. Replace `/dev/ttyUSB0` with the actual serial port if needed:
3952

4053
```bash
41-
idf.py dfu
54+
idf.py -p /dev/ttyUSB0 flash
4255
```
4356

44-
#### Flash the project
57+
After flashing, move the USB cable to the native USB connector before running the example.
58+
59+
#### Flash using native USB
4560

46-
Put the ESP32-S2/S3 into bootloader mode and run the following command:
61+
If you want to avoid moving the USB cable between flashing and running the example, flash through the native USB connector.
62+
63+
For ESP32-S2, enter USB DFU bootloader mode by holding BOOT, resetting the board, and then releasing BOOT. Then run:
4764

4865
```bash
66+
idf.py dfu
4967
idf.py dfu-flash
5068
```
5169

70+
For ESP32-S3, the native USB connector commonly enumerates as USB-JTAG/serial in bootloader mode. Replace `/dev/ttyACM0` with the actual USB-JTAG/serial port if needed:
71+
72+
```bash
73+
idf.py -p /dev/ttyACM0 flash
74+
```
75+
76+
After flashing, reset the board and let the application start. With the default configuration, the application exposes two USB-CDC ACM ports over the native USB connector: one for micro-ROS communication and one for log output.
77+
5278
### Run micro-ROS Agent
5379

80+
Use the micro-ROS communication CDC port from the native USB connector, usually `/dev/ttyACM0`:
81+
5482
```bash
5583
export ROS_DOMAIN_ID=100 # Set the ROS2 domain ID
5684
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0
5785
```
5886

87+
Or, using Docker:
88+
89+
```bash
90+
docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:rolling serial --dev /dev/ttyACM0 -v4
91+
```
92+
5993
Output expected:
6094

6195
```bash
6296
[1724443525.673894] info | TermiosAgentLinux.cpp | init | running... | fd: 3
6397
[1724443525.674071] info | Root.cpp | set_verbose_level | logger setup | verbose_level: 4
64-
[1724443529.936542] info | TermiosAgentLinux.cpp | init | running... | fd: 3
6598
[1724443531.062646] info | Root.cpp | create_client | create | client_key: 0x3E801A05, session_id: 0x81
6699
[1724443531.062805] info | SessionManager.hpp | establish_session | session established | client_key: 0x3E801A05, address: 0
67100
[1724443531.107532] info | ProxyClient.cpp | create_participant | participant created | client_key: 0x3E801A05, participant_id: 0x000(1)
@@ -80,16 +113,16 @@ ros2 topic list
80113
Output expected:
81114

82115
```bash
83-
/esp32s2/int32_publisher_usbcdc
116+
/<target>/int32_publisher_usbcdc
84117
/parameter_events
85118
/rosout
86119
```
87120

88-
And see if the `esp32s2/int32_publisher_usbcdc` topic is available. You can echo the topic to see the messages:
121+
The `<target>` part is the configured ESP-IDF target, for example `esp32s2` or `esp32s3`. You can echo the topic to see the messages:
89122

90123
```bash
91124
export ROS_DOMAIN_ID=100 # Set the ROS2 domain ID
92-
ros2 topic echo esp32s2/int32_publisher_usbcdc
125+
ros2 topic echo /<target>/int32_publisher_usbcdc
93126
```
94127

95128
Output expected:

‎examples/int32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_logging/CMakeLists.txt‎

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎examples/int32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_transport/esp32s2_usbcdc_transport.h‎

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
idf_component_register(SRCS "esp_usbcdc_logging.c" INCLUDE_DIRS ".")

examples/int32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_logging/esp32s2_usbcdc_logging.c renamed to examples/int32_publisher_custom_transport_usbcdc/components/esp_usbcdc_logging/esp_usbcdc_logging.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#include "esp32s2_usbcdc_logging.h"
1+
#include "esp_usbcdc_logging.h"
22

33
// Initialize USB-CDC logging
4-
esp_err_t esp32s2_usbcdc_logging_init(void)
4+
esp_err_t esp_usbcdc_logging_init(void)
55
{
66
const tinyusb_config_t tinyusb_config = {
77
.descriptor = NULL,
@@ -38,7 +38,7 @@ esp_err_t esp32s2_usbcdc_logging_init(void)
3838
}
3939

4040
// Deinitialize USB-CDC logging
41-
esp_err_t esp32s2_usbcdc_logging_deinit(void)
41+
esp_err_t esp_usbcdc_logging_deinit(void)
4242
{
4343
esp_err_t ret = esp_tusb_deinit_console(TINYUSB_CDC_ACM_1);
4444

examples/int32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_logging/esp32s2_usbcdc_logging.h renamed to examples/int32_publisher_custom_transport_usbcdc/components/esp_usbcdc_logging/esp_usbcdc_logging.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef ESP32S2_USBCDC_LOGGING_H
2-
#define ESP32S2_USBCDC_LOGGING_H
1+
#ifndef ESP_USBCDC_LOGGING_H
2+
#define ESP_USBCDC_LOGGING_H
33

44
#include "esp_err.h"
55
#include "tinyusb.h"
@@ -18,8 +18,8 @@ extern "C"
1818
{
1919
#endif
2020

21-
esp_err_t esp32s2_usbcdc_logging_init(void);
22-
esp_err_t esp32s2_usbcdc_logging_deinit(void);
21+
esp_err_t esp_usbcdc_logging_init(void);
22+
esp_err_t esp_usbcdc_logging_deinit(void);
2323

2424
#ifdef __cplusplus
2525
}
@@ -29,4 +29,4 @@ esp_err_t esp32s2_usbcdc_logging_deinit(void);
2929
#error "Logging over USB-CDC is only supported on ESP32-S2 or ESP32-S3 targets"
3030
#endif
3131

32-
#endif // ESP32S2_USBCDC_LOGGING_H
32+
#endif // ESP_USBCDC_LOGGING_H

examples/int32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_logging/idf_component.yml renamed to examples/int32_publisher_custom_transport_usbcdc/components/esp_usbcdc_logging/idf_component.yml

File renamed without changes.

examples/int32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_transport/CMakeLists.txt renamed to examples/int32_publisher_custom_transport_usbcdc/components/esp_usbcdc_transport/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
idf_component_register(SRCS "esp32s2_usbcdc_transport.c"
1+
idf_component_register(SRCS "esp_usbcdc_transport.c"
22
INCLUDE_DIRS "."
33
REQUIRES micro_ros_espidf_component # include <uxr/client/transport.h>
44
)

examples/int32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_transport/esp32s2_usbcdc_transport.c renamed to examples/int32_publisher_custom_transport_usbcdc/components/esp_usbcdc_transport/esp_usbcdc_transport.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#include "esp32s2_usbcdc_transport.h"
1+
#include "esp_usbcdc_transport.h"
22

33
// Open USB-CDC
4-
bool esp32s2_usbcdc_open(struct uxrCustomTransport* transport) {
4+
bool esp_usbcdc_open(struct uxrCustomTransport* transport) {
55
const tinyusb_config_t tinyusb_config = {
66
.device_descriptor = NULL,
77
.string_descriptor = NULL,
@@ -12,7 +12,7 @@ bool esp32s2_usbcdc_open(struct uxrCustomTransport* transport) {
1212
esp_err_t ret = tinyusb_driver_install(&tinyusb_config);
1313

1414
if (ret == ESP_ERR_INVALID_ARG || ret == ESP_FAIL) {
15-
return ret;
15+
return false;
1616
}
1717

1818
tinyusb_cdcacm_itf_t* cdc_port = (tinyusb_cdcacm_itf_t*)transport->args;
@@ -35,23 +35,23 @@ bool esp32s2_usbcdc_open(struct uxrCustomTransport* transport) {
3535
}
3636

3737
// Close USB-CDC
38-
bool esp32s2_usbcdc_close(struct uxrCustomTransport* transport) {
38+
bool esp_usbcdc_close(struct uxrCustomTransport* transport) {
3939
tinyusb_cdcacm_itf_t* cdc_port = (tinyusb_cdcacm_itf_t*)transport->args;
4040
return (tusb_cdc_acm_deinit(*cdc_port) == ESP_OK) ? true : false;
4141
}
4242

4343
// Write to USB-CDC
44-
size_t esp32s2_usbcdc_write(struct uxrCustomTransport* transport, const uint8_t* buf, size_t len, uint8_t* err) {
44+
size_t esp_usbcdc_write(struct uxrCustomTransport* transport, const uint8_t* buf, size_t len, uint8_t* err) {
4545
tinyusb_cdcacm_itf_t* cdc_port = (tinyusb_cdcacm_itf_t*)transport->args;
4646
size_t tx_size = tinyusb_cdcacm_write_queue(*cdc_port, buf, len);
4747
tinyusb_cdcacm_write_flush(*cdc_port, 0);
4848
return tx_size;
4949
}
5050

5151
// Read from USB-CDC
52-
size_t esp32s2_usbcdc_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err) {
52+
size_t esp_usbcdc_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err) {
5353
tinyusb_cdcacm_itf_t* cdc_port = (tinyusb_cdcacm_itf_t*)transport->args;
5454
size_t rx_size = 0;
5555
esp_err_t ret = tinyusb_cdcacm_read(*cdc_port, buf, len, &rx_size);
5656
return (ret == ESP_OK) ? rx_size : 0;
57-
}
57+
}

0 commit comments

Comments
 (0)