Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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);
#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