This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 18b67b3de899cb95a92a7858d14abc2724127092
Author: raiden00pl <[email protected]>
AuthorDate: Thu Jun 11 20:14:46 2026 +0200

    arch/nrf91: implement LTE PSM/eDRX via the LAPI
    
    Add LTE_CMDID_SETPSM / LTE_CMDID_SETEDRX handling that encodes the requested
    PSM (T3412/T3324) and eDRX timers to AT+CPSMS / AT+CEDRXS, so the LTE power
    saving modes are controllable through the common LTE API.
    
    Signed-off-by: raiden00pl <[email protected]>
---
 arch/arm/src/nrf91/nrf91_modem_sock.c | 134 ++++++++++++++++++++++++++++++++++
 1 file changed, 134 insertions(+)

diff --git a/arch/arm/src/nrf91/nrf91_modem_sock.c 
b/arch/arm/src/nrf91/nrf91_modem_sock.c
index c85557e32d2..2b190ee2d2a 100644
--- a/arch/arm/src/nrf91/nrf91_modem_sock.c
+++ b/arch/arm/src/nrf91/nrf91_modem_sock.c
@@ -606,6 +606,124 @@ static int nrf91_modem_actpdn(FAR lte_apn_setting_t *apn,
   return OK;
 }
 
+/****************************************************************************
+ * Name: nrf91_modem_bits
+ *
+ * Description:
+ *   Format the low 'nbits' of 'value' as a binary string (MSB first), as
+ *   used by the 3GPP timer fields of AT+CPSMS and AT+CEDRXS.
+ *
+ * Input Parameters:
+ *   value - Value to format.
+ *   nbits - Number of low-order bits to emit.
+ *   out   - Output buffer (must hold at least nbits + 1 bytes).
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void nrf91_modem_bits(uint8_t value, int nbits, FAR char *out)
+{
+  int i;
+
+  for (i = 0; i < nbits; i++)
+    {
+      out[i] = (value & (1 << (nbits - 1 - i))) ? '1' : '0';
+    }
+
+  out[nbits] = '\0';
+}
+
+/****************************************************************************
+ * Name: nrf91_modem_setpsm
+ *
+ * Description:
+ *   Apply PSM settings (LTE_CMDID_SETPSM) by translating the LAPI
+ *   lte_psm_setting_t into the AT+CPSMS command.
+ *
+ * Input Parameters:
+ *   psm - PSM settings to apply.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int nrf91_modem_setpsm(FAR lte_psm_setting_t *psm)
+{
+  /* LAPI timer-unit enums -> 3GPP encoded unit bits (TS 24.008 GPRS timers).
+   * T3412 extended (periodic TAU) and T3324 (active time).
+   */
+
+  static const uint8_t t3412[] =
+    {
+      3, 4, 5, 0, 1, 2, 6, 7  /* 2s,30s,1m,10m,1h,10h,320h,deact */
+    };
+
+  static const uint8_t t3324[] =
+    {
+      0, 1, 2, 7              /* 2s,1m,6m,deact */
+    };
+
+  char tau[9];
+  char act[9];
+  uint8_t b;
+
+  if (!psm->enable)
+    {
+      return nrf_modem_at_printf("AT+CPSMS=0");
+    }
+
+  b = (uint8_t)((t3412[psm->ext_periodic_tau_time.unit & 0x7] << 5) |
+                (psm->ext_periodic_tau_time.time_val & 0x1f));
+  nrf91_modem_bits(b, 8, tau);
+
+  b = (uint8_t)((t3324[psm->req_active_time.unit & 0x3] << 5) |
+                (psm->req_active_time.time_val & 0x1f));
+  nrf91_modem_bits(b, 8, act);
+
+  return nrf_modem_at_printf("AT+CPSMS=1,,,\"%s\",\"%s\"", tau, act);
+}
+
+/****************************************************************************
+ * Name: nrf91_modem_setedrx
+ *
+ * Description:
+ *   Apply eDRX settings (LTE_CMDID_SETEDRX) by translating the LAPI
+ *   lte_edrx_setting_t into the AT+CEDRXS command.
+ *
+ * Input Parameters:
+ *   edrx - eDRX settings to apply.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int nrf91_modem_setedrx(FAR lte_edrx_setting_t *edrx)
+{
+  char value[5];
+  int  acttype;
+
+  if (!edrx->enable || edrx->act_type == LTE_EDRX_ACTTYPE_NOTUSE)
+    {
+      /* Disable eDRX and discard any stored value */
+
+      return nrf_modem_at_printf("AT+CEDRXS=3");
+    }
+
+  /* AT+CEDRXS access technology: 4 = E-UTRAN WB-S1 (LTE-M),
+   * 5 = E-UTRAN NB-S1 (NB-IoT). The LAPI eDRX cycle enum matches the 4-bit
+   * 3GPP requested-eDRX value directly.
+   */
+
+  acttype = (edrx->act_type == LTE_EDRX_ACTTYPE_NBS1) ? 5 : 4;
+  nrf91_modem_bits((uint8_t)(edrx->edrx_cycle & 0xf), 4, value);
+
+  return nrf_modem_at_printf("AT+CEDRXS=2,%d,\"%s\"", acttype, value);
+}
+
 /****************************************************************************
  * Name: nrf91_ioctl_ltecmd
  ****************************************************************************/
@@ -719,6 +837,22 @@ static int nrf91_ioctl_ltecmd(int fd, int cmd, unsigned 
long arg)
         break;
       }
 
+      case LTE_CMDID_SETPSM:
+        {
+          lte_psm_setting_t **psm =
+            (lte_psm_setting_t **)(ltecmd->inparam);
+          ret = nrf91_modem_setpsm(*psm);
+          break;
+        }
+
+      case LTE_CMDID_SETEDRX:
+        {
+          lte_edrx_setting_t **edrx =
+            (lte_edrx_setting_t **)(ltecmd->inparam);
+          ret = nrf91_modem_setedrx(*edrx);
+          break;
+        }
+
       /* TODO: commands from include/nuttx/wireless/lte/lte.h */
 
       default:

Reply via email to