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:
