Skip to content

PPP.begin() fails when modem is in CMUX mode and RST is not defined #10237

Closed
@szerwi

Description

@szerwi

Board

ESP32 S3

Device Description

ESP32 S3 DevKitC

Hardware Configuration

ESP32 connected to SIM7600E (BK-SIM7600E board) using only RX and TX, without RST pin.

Version

v3.0.4

IDE Name

PlatformIO (Arduino as ESP IDF component)

Operating System

Windows 10

Flash frequency

40MHz

PSRAM enabled

no

Upload speed

115200

Description

When RST pin in GSM modem is not used, it is not possible to reconnect to the module (eg. call PPP.begin() after ESP32 restart) when the modem was already switched to CMUX mode.

PPP::begin() tries to switch from data mode to command mode when it does not get the proper response for AT command, but it does not consider the case when the modem is in CMUX mode.

I have managed to temporary fix it by making changes in PPP::begin(), starting from line 312: https://github.com/espressif/arduino-esp32/blob/master/libraries/PPP/src/PPP.cpp#L312

/* Wait for Modem to respond */
  if (_pin_rst >= 0) {
    // wait to be able to talk to the modem
    log_v("Waiting for response from the modem");
    while (esp_modem_sync(_dce) != ESP_OK && trys < 100) {
      trys++;
      delay(500);
    }
    if (trys >= 100) {
      log_e("Failed to wait for communication");
      goto err;
    }
  } else {
    // try to communicate with the modem
    if (esp_modem_sync(_dce) != ESP_OK) {
      log_v("Modem does not respond to AT, maybe in DATA mode? ...exiting network mode");

    // 
    // FIX START
    //
      log_v("Force switching mode to CMUX");
      _mode = ESP_MODEM_MODE_CMUX;

      log_v("Switching mode to command");
      esp_err_t cmd_err = esp_modem_set_mode(_dce, ESP_MODEM_MODE_COMMAND);
      if(cmd_err != ESP_OK) {
        log_w("Failed to switch mode to COMMAND! %d", cmd_err);
      }
      else {
        log_v("Mode switched to COMMAND");
      }

      log_v("Switching mode to CMUX");
      esp_err_t cmux_err = esp_modem_set_mode(_dce, ESP_MODEM_MODE_CMUX);
      if(cmux_err != ESP_OK) {
        log_w("Failed to switch mode to CMUX! %d", cmux_err);
      }
      else {
        log_v("Mode switched to CMUX");
      }

      //esp_modem_set_mode(_dce, ESP_MODEM_MODE_COMMAND);

    // 
    // FIX END
    //

      if (esp_modem_sync(_dce) != ESP_OK) {
        log_e("Modem failed to respond to AT!");
        goto err;
      }
    }
  }

The change is that when RST pin is not used and it did not receive response for AT command, it force switches to CMUX mode, then switches to COMMAND mode and again to CMUX mode. I believe there should be a cleaner method to achieve the same result, however, I haven't came up with one yet.

I can make a PR with the fix, but I have created the issue first to get some feedback & help with the best way to fix that issue.

Sketch

#include <Arduino.h>
#include <PPP.h>

#define PPP_MODEM_APN "internet"
#define PPP_MODEM_PIN "0000" // or NULL

#define PPP_MODEM_TX 21
#define PPP_MODEM_RX 47
#define PPP_MODEM_FC ESP_MODEM_FLOW_CONTROL_NONE
#define PPP_MODEM_MODEL PPP_MODEM_SIM7600

static bool ppp_connected = false;

void onEvent(arduino_event_id_t event, arduino_event_info_t info)
{
  switch (event)
  {
  case ARDUINO_EVENT_PPP_START:
    Serial.println("PPP Started");
    break;
  case ARDUINO_EVENT_PPP_CONNECTED:
    Serial.println("PPP Connected");
    break;
  case ARDUINO_EVENT_PPP_GOT_IP:
    Serial.println("PPP Got IP");
    ppp_connected = true;
    break;
  case ARDUINO_EVENT_PPP_LOST_IP:
    Serial.println("PPP Lost IP");
    ppp_connected = false;
    break;
  case ARDUINO_EVENT_PPP_DISCONNECTED:
    Serial.println("PPP Disconnected");
    ppp_connected = false;
    break;
  case ARDUINO_EVENT_PPP_STOP:
    Serial.println("PPP Stopped");
    ppp_connected = false;
    break;
  default:
    break;
  }
}

void testClient(const char *host, uint16_t port)
{
  Serial.print("\nconnecting to ");
  Serial.println(host);

  NetworkClient client;
  if (!client.connect(host, port))
  {
    Serial.println("connection failed");
    return;
  }
  client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
  while (client.connected() && !client.available())
    ;

  while (client.available())
  {
    Serial.write(client.read());
  }

  Serial.println("closing connection\n");
  client.stop();
}

void setup()
{
  esp_log_level_set("*", ESP_LOG_VERBOSE);
  Serial.begin(115200);
  Network.onEvent(onEvent);

  PPP.setApn(PPP_MODEM_APN);
  PPP.setPin(PPP_MODEM_PIN);
  PPP.setPins(PPP_MODEM_TX, PPP_MODEM_RX);

  Serial.println("Starting the modem. It might take a while!");
  if (!PPP.begin(PPP_MODEM_MODEL))
  {
    Serial.println("Failed to start the modem!");
  }
  else
  {
    Serial.println("PPP modem started");
  }

  Serial.print("Manufacturer: ");
  Serial.println(PPP.cmd("AT+CGMI", 10000));
  Serial.print("Model: ");
  Serial.println(PPP.moduleName());
  Serial.print("IMEI: ");
  Serial.println(PPP.IMEI());

  bool attached = PPP.attached();
  if (!attached)
  {
    int i = 0;
    unsigned int s = millis();
    Serial.print("Waiting to connect to network");
    while (!attached && ((++i) < 600))
    {
      Serial.print(".");
      delay(100);
      attached = PPP.attached();
    }
    Serial.print((millis() - s) / 1000.0, 1);
    Serial.println("s");
    attached = PPP.attached();
  }

  Serial.print("Attached: ");
  Serial.println(attached);
  Serial.print("State: ");
  Serial.println(PPP.radioState());
  if (attached)
  {
    Serial.print("Operator: ");
    Serial.println(PPP.operatorName());
    Serial.print("IMSI: ");
    Serial.println(PPP.IMSI());
    Serial.print("RSSI: ");
    Serial.println(PPP.RSSI());
    int ber = PPP.BER();
    if (ber > 0)
    {
      Serial.print("BER: ");
      Serial.println(ber);
      Serial.print("NetMode: ");
      Serial.println(PPP.networkMode());
    }

    Serial.println("Switching to data mode...");
    PPP.mode(ESP_MODEM_MODE_CMUX); // Data and Command mixed mode
    if (!PPP.waitStatusBits(ESP_NETIF_CONNECTED_BIT, 10000))
    {
      Serial.println("Failed to connect to internet!");
    }
    else
    {
      Serial.println("Connected to internet!");
    }
  }
  else
  {
    Serial.println("Failed to connect to network!");
  }
}

void loop()
{
  if (ppp_connected)
  {
    testClient("google.com", 80);
  }
  else
  {
    Serial.println("No network connected");
  }

  delay(5000);
}

Debug Message

[   675][V][esp32-hal-uart.c:408] uartBegin(): UART0 baud(115200) Mode(800001c) rxPin(44) txPin(43)
[   684][V][esp32-hal-uart.c:497] uartBegin(): UART0 not installed. Starting installation
[   693][V][esp32-hal-uart.c:560] uartBegin(): UART0 initialization done.
[   699][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type PPP_MODEM_TX (48) successfully set to 0x42006828
[   711][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type PPP_MODEM_RX (49) successfully set to 0x42006828
[   723][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type PPP_MODEM_RTS (50) successfully set to 0x42006828
[   735][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type PPP_MODEM_CTS (51) successfully set to 0x42006828
[   747][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 21 successfully set to type PPP_MODEM_TX (48) with bus 0x3fc96adc
[   758][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 47 successfully set to type PPP_MODEM_RX (49) with bus 0x3fc96adc
Starting the modem. It might take a while!
[  1271][V][PPP.cpp:327] begin(): Modem does not respond to AT, maybe in DATA mode? ...exiting network mode
[  1281][V][PPP.cpp:132] _onPppEvent(): PPP Driver Event 5: User interrupt.
[  5700][E][PPP.cpp:330] begin(): Modem failed to respond to AT!
[  5706][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 44 - PPP_STOP
PPP Stopped
[  5714][V][NetworkInterface.cpp:264] destroyNetif(): Unregistered event handler
[  5722][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 47 successfully set to type INIT (0) with bus 0x0
[  5732][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 21 successfully set to type INIT (0) with bus 0x0
Failed to start the modem!
Manufacturer:
Model: 
IMEI:
Waiting to connect to network...

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions