-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the ability to resume CMUX (or other modem modes) when waking up from deep sleep (IDFGH-14047) #692
Comments
Have you tried the new mode-detection feature? -- released yesterday as v1.2.0
The idea is that you issue |
That release does seem to have a lot of features I have been needing. Unfortunately it does not seem to be working for me. In my code, on startup the modem boots up and I set the mode to CMUX mode. This works great and I am able to get data and commands working without any problem. Then when the MCU enters deep sleep the netif and DCE are deinited. When the MCU wakes from deep sleep I set the mode to case modem_mode::AUTODETECT: {
auto guessed = guess_unsafe(dte, true);
if (guessed == modem_mode::UNDEF) { // AUTODETECT failing because of this response
printf("Guessed mode is undefined\n"); // Added print to see where it was failing
return false;
} Also even if the Here are the results from trying to resume using the different resume modes that are provided:
I also tried resuming modes, and being in CMUX manual prior to deep sleep, and it still gave me the same results as above, with no modem commands or data working. Is there something else I am missing or anything special needed prior to entering deep sleep or after wakeup? I am using the C APIs. A brief overview of my modem setup and teardown is shown below:C API function to allow resume modes from Cextern "C" esp_err_t esp_modem_resume_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce_resume_mode_t mode)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
switch (mode) {
case ESP_MODEM_RESUME_DATA_MODE:
return dce_wrap->dce->set_mode(modem_mode::RESUME_DATA_MODE) ? ESP_OK : ESP_FAIL;
case ESP_MODEM_RESUME_COMMAND_MODE:
return dce_wrap->dce->set_mode(modem_mode::RESUME_COMMAND_MODE) ? ESP_OK : ESP_FAIL;
case ESP_MODEM_RESUME_CMUX_MANUAL_MODE:
return dce_wrap->dce->set_mode(modem_mode::RESUME_CMUX_MANUAL_MODE) ? ESP_OK : ESP_FAIL;
case ESP_MODEM_RESUME_CMUX_MANUAL_DATA:
return dce_wrap->dce->set_mode(modem_mode::RESUME_CMUX_MANUAL_DATA) ? ESP_OK : ESP_FAIL;
case ESP_MODEM_AUTODETECT:
return dce_wrap->dce->set_mode(modem_mode::AUTODETECT) ? ESP_OK : ESP_FAIL;
return ESP_ERR_NOT_SUPPORTED;
}
} Inside wakeup/startupesp_netif_config_t netif_ppp_config = ESP_NETIF_DEFAULT_PPP();
esp_netif_t * net_if = esp_netif_new(&netif_ppp_config);
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(apn);
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
esp_modem_dce_t* dce = esp_modem_new_dev(ESP_MODEM_DCE_CUSTOM, &dte_config, &dce_config, net_if);
esp_err_t ret;
if (deep_sleep_wakeup) {
// Wake from deep sleep, modem is not rebooted and should resume previous mode
ret = esp_modem_resume_mode(dce, ESP_MODEM_AUTODETECT);
// I have tried all of the available resume modes, but none make the commands and data work again,
// despite 3 of the 5 modes returning ESP_OK (see list above for results for each mode).
} else {
// Regular startup. Modem was rebooted
ret = esp_modem_set_mode(dce,ESP_MODEM_MODE_CMUX);
}
printf("Modem mode setup: %s\n",esp_err_to_name(ret)); Inside prepare for deep sleepesp_modem_destroy(dce);
esp_netif_destroy(net_if); As a note, I am using the Qualcomm QCX216 modem. |
I haven't tested it with many devices, but I'm surprised it won't work even with basic command and data modes? Could you please share more logs after applying these changes:
Let's start with these simple scenarios (no CMUX for now):
And if you can share the logs from these two procedures above, it would be really helpful! |
Thank you so much for your help with this issue, it has been blocking me for quite some time now. I performed the tests you requested. In the resume CMD mode, there was no issues and I didnt expect there to one any problems with that mode. For the sake of efficiency, I also provided the logs for the same test using the CMUX and AUTO/CMUX resume modes. This is not working and is the use case I need. In my project we need to be able to use the PPP data and send commands to the modem. Switching out of CMUX mode before sleeping is not preferred since the modem is reset when exiting CMUX, and I would need to wait for startup and connect to PPP. This causes a 10-30 second delay in the deep sleep setup, which will not work. The other option would be to restart the modem every time the MCU wakes from deep sleep, but that also causes the delay in the startup process and I need the device to be able to make a quick connection. I have tried the USB DCE to use the 2 interfaces for data and commands, which works, but this is not an option due to the higher power usage of USB compared to UART. From an analysis of the modem log, it appears that in the case of the resume CMUX/AUTO/PPP modes, the modem did not receive any data from the MCU after wakeup from deep sleep. The init and startup process is not different based on the modes, as I am manually entering and resuming modes for these tests. test-Resume CMUX mode.txt |
So you're also setting your device to a low power mode, correct?
should succeed and resume the command mode (i.e. do nothing). |
I am not intentionally setting the modem to low power mode or changing anything on the modem. I am sending no commands to the modem as part of the enter sleep. I am not sure if the modem is timing out or reverting to a different state when the MCU is asleep/not responding. I am working with Qualcomm to better understand that, but from the logs I have reviewed and my understanding, that is not happening in the CMUX case even though something like that does appear to be happening in the PPP mode, but perhaps not when CMUX is enabled. I did the repeat the test by setting data mode to enter PPP This test was successfully and resumed to CMD mode, as we would expect since in earlier test it entered CMD mode on wakeup. So in the case of PPP and CMD, the resume options are working. The real issue I am facing is with the CMUX. CMUX resume is not working and neither is AUTO, when the mode was in CMUX prior to sleeping. The closest method I have to a successful case with CMUX is as follow:
In this test I did not use any of the resume functionality, just the standard set modes. As part of startup I enter CMUX manual then transition to CMUX manual data. This is the same behavior whether the device is waking up from deep sleep or initial startup. Then to prepare for deep sleep the mode is set to CMUX manual command then to CMUX exit. If the CMUX is properly exited prior to sleep, I am able to use the modem and enter CMUX manual again after wakeup. The reason I need to go to CMUX manual command prior to the CMUX exit is due to the fact that the modem reboots if the CMUX is exited from an active CMUX data state, but not from a CMUX command state. This speeds up the prepare for sleep process. There does seem to be an issue when transitioning from CMUX data to CMUX command. It sends the The successful CMUX test case mentioned above could be a viable solution if we can figure out why the |
@jlittlewood Could you please test the CMUX manual data -> cmd transition with this update? --- a/components/esp_modem/src/esp_modem_dce.cpp
+++ b/components/esp_modem/src/esp_modem_dce.cpp
@@ -18,7 +18,6 @@ namespace transitions {
static bool exit_data(DTE &dte, ModuleIf &device, Netif &netif)
{
- netif.stop();
auto signal = std::make_shared<SignalGroup>();
std::weak_ptr<SignalGroup> weak_signal = signal;
dte.set_read_cb([&netif, weak_signal](uint8_t *data, size_t len) -> bool {
@@ -44,6 +43,7 @@ static bool exit_data(DTE &dte, ModuleIf &device, Netif &netif)
}
return false;
});
+ netif.stop();
netif.wait_until_ppp_exits();
if (!signal->wait(1, 2000)) { (moving the |
@david-cermak I applied the suggested changes, but it did not make a difference. I looked closer in the logs from today and the logs I provided on my previous post and noticed that the
Here it is obvious that the modem sent the |
Yes, you're right, the answer is coming from the other terminal.
Could you please try to swap the terminal before going to
so the procedure would be (saw that you're using modem console):
PS: I'm sorry, the manual cmux modes are not documented well; switching the terminals is necessary since we switch the current terminal to data and need to reserve the former one to commands (this actually mimics the standard CMUX transition). |
Is your feature request related to a problem?
I am using the esp_modem library and my device needs to support deep sleep. I need access to commands and data through UART, so I need to use CMUX mode. I am not aware of any way to set the DCE to CMUX mode on wakeup, when the modem is already in CMUX mode. When the DCE is initialized after wakeup it is in an undefined mode, which allows switching to any mode, but with the modem already set up and communicating in CMUX mode, simply running the set_mode to CMUX will not work, since it is dependent on various responses from the modem which may be communicating on different channels due to the CMUX setting being active on the modem.
Describe the solution you'd like.
Ideally, there would be a way to resume a mode upon initialization. The resume will assume the modem is already in the perspective mode and set up the DCE, netif, and UART terminals based on the mode that is being resumed.
Describe alternatives you've considered.
I have attempted to make my own CMUX resume function in the DCE that would set up the primary and secondary terminals and start the netif, but would not fail based on responses from the modem. This method has not been successful. I have not been able to get data to work, and commands usually don't work either.
Another option is to reset the modem each time, but this is undesirable due to the longer time to boot up the modem and connect. I need the modem to be ready as fast as possible from deep sleep wakeup.
Similarly, I have tried changing the modes prior to entering sleep. This has been problematic because I need the modem to be in PPP mode (or CMUX) while the MCU is asleep, so I can get the GPIO wake-ups for incoming data. This method also slows down the sleep process.
Additional context.
I am using an ESP32-S3 and the esp_modem library for UART modem connectivity. The CMUX works fine after the modem is rebooted. The main issue is how to get the DCE mode to match the modem mode that was set prior to the deep sleep.
The text was updated successfully, but these errors were encountered: