-
Notifications
You must be signed in to change notification settings - Fork 8.1k
modem: cmux: UART power control using CMUX Power Saving Control messages #97362
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
base: main
Are you sure you want to change the base?
modem: cmux: UART power control using CMUX Power Saving Control messages #97362
Conversation
1368e5f to
de7938f
Compare
de7938f to
9bd2b3f
Compare
|
I dropped the DTR-UART driver away from this PR. This is now a complete PR that will bring power saving mode into cellular modem and optionally allows shutting down the UART. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, there is the serialization issue which is what is blocking, otherwise really nice additions!
9bd2b3f to
eff0368
Compare
|
@bjarki-andreasen I submitted a separate PR as it looks like all CMUX command structures relied on same bitfield behavior, so I fixed all of those. This PR contains the fix for PSC as well as the requested pipe test. |
eff0368 to
14d1947
Compare
Instead of relying non-standard compiler behavior, define encode and decode functions for all CMUX command structures. Final command is encoded into a shared buffer, because it is always copied directly to TX ringbuffer. Added also functions to validate commands. Signed-off-by: Seppo Takalo <[email protected]>
Signal powersaving mode for the remote end using PSC command. Wakes up the remote end from powersaving mode by sending flag characters. This method is defined in 3GPP TS 27.010. Sections 5.4.6.3.2 Power Saving Control (PSC) and 5.4.7 Power Control and Wake-up Mechanisms. Essentially it is one PSC command to indicate a sleep state, and then repeated flag characters to wake up the remote end or indicate that we have been woken up. Signed-off-by: Seppo Takalo <[email protected]>
CMUX driver can enable the support for idle-timer in devicetree and can be requested to shut down the pipe during sleep. Then UART backend put the actual device into sleep when pipe is closed. Waking up is requested by sending data to DLC pipe or by manually opening the uart_pipe. Modem may request similar wake-up by a RING interrupt which would open the same pipe. When UART is powered and pipe is not closed, CMUX wake-up procedure is automatic. Either end may initiate the wake-up. Signed-off-by: Seppo Takalo <[email protected]>
Ringbuffer is not safe in ISR but k_pipe without waiting is. So use pipe for events, so that possible GPIO callbacks from ISR content can post events. Signed-off-by: Seppo Takalo <[email protected]>
Use ring indicator to wake up the CMUX device from sleep. Only used for runtime power management, but same event could be used for initiating idle -> connected as well. Signed-off-by: Seppo Takalo <[email protected]>
Add documentation and state machine diagrams for CMUX power saving feature and how to use it with Zephyr. Signed-off-by: Seppo Takalo <[email protected]>
Instead of copying all fields from cmux_config into run-time struct cmux, just have the configuration structure as a member. Signed-off-by: Seppo Takalo <[email protected]>
When working on CMUX power saving, it is typical that we end up closing the pipe before the last RX_READY event is handled from workqueue, so we end up receiving -EPERM which is not really a fatal error. Pipes recover when they are re-opened. So drop this error and return zero instead, like modem_pipe_open() and close() does. Signed-off-by: Seppo Takalo <[email protected]>
14d1947 to
3ffa7d1
Compare
|



I'm putting up this PR as a RFC for now until I have been able to split the smaller commits to separate PR and to allow reviewers to see what the end goal is. It is easier to argue why I change something if I show the intent here.
I have so far submitted changes from this work on following PRs:
Description of the work: CMUX Power Saving
The 3GPP TS 27.010 specifies a power saving mechanism for CMUX which can be used in Zephyr when the modem supports it.
The power saving mechanism is covered in the following sections on the specification:
States are explained in the generated documen in OS Services -> Modem Modules.
The power saving mechanism allows runtime power management for the UART device used by the CMUX module. When there is no data to be sent or received on any DLCI channel, the CMUX module will enter the idle state after a configurable timeout. In the idle state, the CMUX module will send a Power Saving Control message to the modem, requesting it to enter a low power state. The CMUX module may then close the pipe device, allowing the UART device to be powered down if runtime power management is enabled.
PIPE backend is in response of actually power controlling the UART as it is the last endpoint in PIPE interface

When data is to be sent or received on any DLCI channel, the CMUX module will exit the idle state and wakes the modem up by sending flag characters until it receives a flag character from the modem.
Some modems allow UART to be powered down only when the DTR (Data Terminal Ready) signal is de-asserted. In this case, a UART device with DTR support can be used with the CMUX module to control the DTR signal based on the power state of the UART.
Waking up on incoming data when UART is powered down requires a modem that supports RING signal to wake up the host. The RING signal is handled by the modem driver and it opens the pipe device when the RING signal is detected, allowing the CMUX module to wake up the modem and process incoming data.
CMUX options are controlled using Device Tree settings, because CMUX is a modem dependant.
Example setup where CMUX power control is enabled and UART is allowed to shut down and control the DTR line:
This PR implements CMUX Power Saving in a way that it allows Zephyr host to keep PPP connection up while the underlying UART is powered down and the module may enter eDRX or PSM sleep modes. Waking up is completely automatic when PPP is sending data. Incoming data wakes up the modem modules using RING signal.
UART power management requires DTR and RING as the CMUX itself can only initiate wake up by sending flag characters.
The usage of DTR pin is typical in such modems that allow disconnecting the UART:

However, even if UART cannot be shut down, modem MAY benefit from the knowledge that CMUX is in the sleep mode.
Without DTR/power off, this PR has been tested against Quectel BG96 modem. With DTR and power control, I have tested this against ongoing work of nRF9160 Serial Modem application.