Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion components/esp_modem/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ else()
set(platform_srcs src/esp_modem_primitives_freertos.cpp
src/esp_modem_api_target.cpp
src/esp_modem_uart.cpp
src/esp_modem_uart_dma.cpp
src/esp_modem_term_uart.cpp
src/esp_modem_netif.cpp)
set(dependencies driver esp_event esp_netif)
set(dependencies driver esp_event esp_netif esp_driver_uart)
Copy link
Collaborator

@tore-espressif tore-espressif Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@david-cermak Is there any ETA for this change?

Currently it breaks our builds with esp-idf/master. (We build esp_modem_usb_dte in our USB CI, which in turn pulls in esp_modem.) https://github.com/espressif/esp-usb/actions/runs/18191462194/job/51787270030?pr=276#step:4:1917

We can temporarily disable the build job if next esp_modem release needs more time

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe...?

Suggested change
set(dependencies driver esp_event esp_netif esp_driver_uart)
set(dependencies esp_event esp_netif esp_driver_uart)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can temporarily disable the build job if next esp_modem release needs more time

Please disable the build for now, got some breaking changes on master already, so I'll have to branch off...

endif()


Expand Down
26 changes: 26 additions & 0 deletions components/esp_modem/examples/modem_console/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,32 @@ that sets up the DCE based on a custom module implemented in the `my_module_dce.
`get_module_name()` method supplying a user defined name, but keeps all other commands the same as defined in the `GenericModule`
class.

### UART DMA Support

This example now supports UART DMA for high-speed data transfers using the ESP-IDF UHCI driver. DMA mode is automatically enabled for ESP32-S3 targets by default, providing:

- **Higher Throughput**: DMA handles data transfer without CPU intervention
- **Better CPU Utilization**: CPU can perform other tasks during data transfer
- **Lower Latency**: Reduced interrupt overhead for large transfers
- **Efficient Memory Usage**: Direct memory access reduces copying

#### Configuration Options

- **Enable UART DMA Support**: `CONFIG_EXAMPLE_MODEM_UART_USE_DMA` (default: y for ESP32-S3)
- **DMA Buffer Size**: `CONFIG_EXAMPLE_MODEM_UART_DMA_BUFFER_SIZE` (default: 8192 bytes)

#### Performance Benefits

DMA mode is most beneficial for:
- High baud rates (> 500 kbps)
- Large data transfers
- Applications requiring high throughput

Traditional UART mode is suitable for:
- Low baud rates
- Small, infrequent transfers
- Power-sensitive applications

### USB DTE support

For USB enabled targets (ESP32-S2, ESP32-S3, or ESP32-P4), it is possible to connect to the modem device via USB.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
Expand All @@ -21,6 +21,7 @@
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#include "esp_modem_uart_dma.h"
#include "esp_idf_version.h"
#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
#include "esp_modem_usb_config.h"
Expand Down Expand Up @@ -135,7 +136,23 @@ extern "C" void app_main(void)
dte_config.task_stack_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE;
dte_config.task_priority = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY;
dte_config.dte_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2;

// Configure DMA options if enabled
#ifdef CONFIG_EXAMPLE_MODEM_UART_USE_DMA
dte_config.uart_config.use_dma = true;
dte_config.uart_config.dma_buffer_size = CONFIG_EXAMPLE_MODEM_UART_DMA_BUFFER_SIZE;
ESP_LOGI(TAG, "UART DMA enabled with buffer size: %zu", dte_config.uart_config.dma_buffer_size);
#else
dte_config.uart_config.use_dma = false;
ESP_LOGI(TAG, "UART DMA disabled, using traditional UART mode");
#endif

// Create DTE with appropriate terminal type
#ifdef CONFIG_EXAMPLE_MODEM_UART_USE_DMA
auto uart_dte = create_uart_dma_dte(&dte_config);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why create a separated function? Isn't the use_dma field not enough to differentiate the call?

#else
auto uart_dte = create_uart_dte(&dte_config);
#endif

#if defined(CONFIG_EXAMPLE_MODEM_DEVICE_SHINY)
ESP_LOGI(TAG, "Initializing esp_modem for the SHINY module...");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=7168
CONFIG_LWIP_PPP_SUPPORT=y
# CONFIG_LWIP_PPP_ENABLE_IPV6 is not set
CONFIG_LWIP_PPP_PAP_SUPPORT=y

# Enable UART DMA by default for ESP32-S3
CONFIG_EXAMPLE_MODEM_UART_USE_DMA=y
CONFIG_EXAMPLE_MODEM_UART_DMA_BUFFER_SIZE=8192
11 changes: 10 additions & 1 deletion components/esp_modem/include/cxx_include/esp_modem_api.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -40,6 +40,15 @@ using dte_config = ::esp_modem_dte_config;
*/
std::shared_ptr<DTE> create_uart_dte(const dte_config *config);

/**
* @brief Create UART DTE with DMA support
* @param config DTE configuration
* @return shared ptr to DTE on success
* nullptr on failure (either due to insufficient memory or wrong dte configuration)
* if exceptions are disabled the API abort()'s on error
*/
std::shared_ptr<DTE> create_uart_dma_dte(const dte_config *config);

/**
* @brief Create VFS DTE
* @param config DTE configuration
Expand Down
4 changes: 4 additions & 0 deletions components/esp_modem/include/esp_modem_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ struct esp_modem_uart_term_config {
int rx_buffer_size; /*!< UART RX Buffer Size */
int tx_buffer_size; /*!< UART TX Buffer Size */
int event_queue_size; /*!< UART Event Queue Size, set to 0 if no event queue needed */
bool use_dma; /*!< Enable UHCI DMA for high-speed transfers */
size_t dma_buffer_size; /*!< DMA buffer size for UHCI transfers */
};

// Forward declare the resource struct
Expand Down Expand Up @@ -114,6 +116,8 @@ struct esp_modem_dte_config {
.rx_buffer_size = 4096, \
.tx_buffer_size = 512, \
.event_queue_size = 30, \
.use_dma = false, \
.dma_buffer_size = 8192, \
}, \
}

Expand Down
43 changes: 43 additions & 0 deletions components/esp_modem/include/esp_modem_uart_dma.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include "esp_modem_config.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Create UART terminal with DMA support
*
* This function creates a UART terminal that can use UHCI DMA for high-speed
* data transfers. The DMA mode is enabled when the `use_dma` flag is set to true
* in the configuration.
*
* @param config Configuration structure for the UART terminal
* @return Pointer to the created terminal, or NULL on failure
*/
void* esp_modem_uart_dma_terminal_create(const esp_modem_dte_config *config);

/**
* @brief Create UART terminal with DMA support (C++ interface)
*
* This is the C++ interface for creating a UART terminal with DMA support.
* It returns a std::unique_ptr<Terminal> for automatic memory management.
*
* @param config Configuration structure for the UART terminal
* @return std::unique_ptr<Terminal> for the created terminal
*/
#ifdef __cplusplus
#include "cxx_include/esp_modem_dte.hpp"
std::unique_ptr<esp_modem::Terminal> create_uart_dma_terminal(const esp_modem_dte_config *config);
#endif

#ifdef __cplusplus
}
#endif
11 changes: 10 additions & 1 deletion components/esp_modem/src/esp_modem_api_target.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -13,6 +13,7 @@
#include "cxx_include/esp_modem_dce_factory.hpp"
#include "esp_modem_config.h"
#include "exception_stub.hpp"
#include "esp_modem_uart_dma.h"

namespace esp_modem {

Expand All @@ -28,4 +29,12 @@ std::shared_ptr<DTE> create_uart_dte(const dte_config *config)
)
}

std::shared_ptr<DTE> create_uart_dma_dte(const dte_config *config)
{
TRY_CATCH_RET_NULL(
auto term = create_uart_dma_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
)
}

} // namespace esp_modem
Loading
Loading