esp_modem: Dual DTE support

Modems can expose 2 terminals, which can be used simultaneously.
One for AT commands, the other one for data.
This commit is contained in:
Tomas Rezucha
2023-03-07 13:35:34 +01:00
parent 08f1f0175d
commit 01c26c82fa
5 changed files with 21 additions and 6 deletions

View File

@ -1,4 +1,4 @@
version: "0.1.27" version: "0.1.28"
description: esp modem description: esp modem
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_modem url: https://github.com/espressif/esp-protocols/tree/master/components/esp_modem
dependencies: dependencies:

View File

@ -39,9 +39,12 @@ public:
* @brief Creates a DTE instance from the terminal * @brief Creates a DTE instance from the terminal
* @param config DTE config structure * @param config DTE config structure
* @param t unique-ptr to Terminal * @param t unique-ptr to Terminal
* @param s unique-ptr to secondary Terminal
*/ */
explicit DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t); explicit DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t);
explicit DTE(std::unique_ptr<Terminal> t); explicit DTE(std::unique_ptr<Terminal> t);
explicit DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s);
explicit DTE(std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s);
~DTE() = default; ~DTE() = default;

View File

@ -27,8 +27,9 @@ namespace esp_modem {
*/ */
enum class modem_mode { enum class modem_mode {
UNDEF, UNDEF,
COMMAND_MODE, /*!< Command mode -- the modem is supposed to send AT commands in this mode */ COMMAND_MODE, /*!< Command mode -- the modem is supposed to send AT commands in this mode */
DATA_MODE, /*!< Data mode -- the modem communicates with network interface on PPP protocol */ DATA_MODE, /*!< Data mode -- the modem communicates with network interface on PPP protocol */
DUAL_MODE, /*!< Dual mode -- the modem has two real terminals. Data and commands work at the same time */
CMUX_MODE, /*!< CMUX (Multiplex mode) -- Simplified CMUX mode, which creates two virtual terminals, CMUX_MODE, /*!< CMUX (Multiplex mode) -- Simplified CMUX mode, which creates two virtual terminals,
* assigning one solely to command interface and the other to the data mode */ * assigning one solely to command interface and the other to the data mode */
CMUX_MANUAL_MODE, /*!< Enter CMUX mode manually -- just creates two virtual terminals */ CMUX_MANUAL_MODE, /*!< Enter CMUX mode manually -- just creates two virtual terminals */

View File

@ -88,6 +88,7 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
{ {
switch (m) { switch (m) {
case modem_mode::UNDEF: case modem_mode::UNDEF:
case modem_mode::DUAL_MODE: // Only DTE can be in Dual mode
break; break;
case modem_mode::COMMAND_MODE: case modem_mode::COMMAND_MODE:
if (mode == modem_mode::COMMAND_MODE || mode >= modem_mode::CMUX_MANUAL_MODE) { if (mode == modem_mode::COMMAND_MODE || mode >= modem_mode::CMUX_MANUAL_MODE) {

View File

@ -24,6 +24,16 @@ DTE::DTE(std::unique_ptr<Terminal> terminal):
cmux_term(nullptr), primary_term(std::move(terminal)), secondary_term(primary_term), cmux_term(nullptr), primary_term(std::move(terminal)), secondary_term(primary_term),
mode(modem_mode::UNDEF) {} mode(modem_mode::UNDEF) {}
DTE::DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s):
buffer(config->dte_buffer_size),
cmux_term(nullptr), primary_term(std::move(t)), secondary_term(std::move(s)),
mode(modem_mode::DUAL_MODE) {}
DTE::DTE(std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s):
buffer(dte_default_buffer_size),
cmux_term(nullptr), primary_term(std::move(t)), secondary_term(std::move(s)),
mode(modem_mode::DUAL_MODE) {}
command_result DTE::command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) command_result DTE::command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator)
{ {
Scoped<Lock> l(internal_lock); Scoped<Lock> l(internal_lock);
@ -104,9 +114,9 @@ bool DTE::set_mode(modem_mode m)
return false; return false;
} }
} }
// transitions (COMMAND|CMUX|UNDEF) -> DATA // transitions (COMMAND|DUAL|CMUX|UNDEF) -> DATA
if (m == modem_mode::DATA_MODE) { if (m == modem_mode::DATA_MODE) {
if (mode == modem_mode::CMUX_MODE || mode == modem_mode::CMUX_MANUAL_MODE) { if (mode == modem_mode::CMUX_MODE || mode == modem_mode::CMUX_MANUAL_MODE || mode == modem_mode::DUAL_MODE) {
// mode stays the same, but need to swap terminals (as command has been switched) // mode stays the same, but need to swap terminals (as command has been switched)
secondary_term.swap(primary_term); secondary_term.swap(primary_term);
} else { } else {
@ -114,7 +124,7 @@ bool DTE::set_mode(modem_mode m)
} }
return true; return true;
} }
// transitions (DATA|CMUX|UNDEF) -> COMMAND // transitions (DATA|DUAL|CMUX|UNDEF) -> COMMAND
if (m == modem_mode::COMMAND_MODE) { if (m == modem_mode::COMMAND_MODE) {
if (mode == modem_mode::CMUX_MODE) { if (mode == modem_mode::CMUX_MODE) {
if (exit_cmux()) { if (exit_cmux()) {
@ -123,7 +133,7 @@ bool DTE::set_mode(modem_mode m)
} }
mode = modem_mode::UNDEF; mode = modem_mode::UNDEF;
return false; return false;
} if (mode == modem_mode::CMUX_MANUAL_MODE) { } if (mode == modem_mode::CMUX_MANUAL_MODE || mode == modem_mode::DUAL_MODE) {
return true; return true;
} else { } else {
mode = m; mode = m;