Multiple Issues Connecting nRF9151 to QM13345 Antenna Switch (No RFFE Support?)

Hello,
I am developing a custom IoT device based on the nRF9151 SiP with a Qorvo QM13345 SP4T antenna switch controlled via RFFE 2.1 interface. All RFFE AT commands fail with error 65536, preventing antenna switch control and resulting in no cellular signal (CSQ: 99,99).

## Hardware Configuration
- **Device**: nRF9151 (nrf9151dk/nrf9151/ns)
- **Antenna Switch**: Qorvo QM13345 SP4T (RFFE 2.1 controlled)
- **Current Modem Firmware**: mfw_nrf91x1_2.0.2
- **SDK**: nRF Connect SDK v3.0.2-89ba1294ac9b
- **Zephyr**: v4.0.99-f791c49f492c

## RFFE Hardware Connections
```
nRF9151          QM13345
Pin 27 -------> SDATA (Pin 5)
Pin 28 -------> SCLK (Pin 6)
Pin 29 -------> VIO (Pin 4)
GND ----------> GND (Pin 7)
```

 **Connections**:
- SDATA (pin 27) → nRF9151 RFFE_SDATA
- SCLK (pin 28) → nRF9151 RFFE_SCLK
- VIO (pin 29) → nRF9151 RFFE_VIO
- RF1 (pin 3) → Main LTE antenna port
- RFC (pin 1) → nRF9151 RF output



QM13345 ID pin connected to solder bridge (SB1/SBI2) for USID configuration.

## Software Configuration
I've enabled Nordic's official modem antenna library:
```kconfig
CONFIG_MODEM_ANTENNA=y
CONFIG_MODEM_ANTENNA_AT_MAGPIO="AT%XMAGPIO=1,0,0,1,1,1574,1577"
CONFIG_MODEM_ANTENNA_AT_MIPIRFFEDEV="AT%XMIPIRFFEDEV=1,7,0"
CONFIG_MODEM_ANTENNA_AT_MIPIRFFECTRL_INIT="AT%XMIPIRFFECTRL=1,0,1,0,1"
CONFIG_MODEM_ANTENNA_AT_MIPIRFFECTRL_ON="AT%XMIPIRFFECTRL=1,1,1,0,1"
CONFIG_MODEM_ANTENNA_AT_MIPIRFFECTRL_OFF="AT%XMIPIRFFECTRL=1,2,1,0,0"
CONFIG_MODEM_ANTENNA_AT_MIPIRFFECTRL_PWROFF="AT%XMIPIRFFECTRL=1,3,1,0,0"
```

## Observed Behavior
During modem initialization, all RFFE configuration attempts fail:
```
[00:00:02.900,329] <err> modem_antenna: Failed to set configuration (err: 65536)
[00:00:02.909,454] <err> modem_antenna: Failed to set configuration (err: 65536)
[00:00:02.924,560] <err> modem_antenna: Failed to set configuration (err: 65536)
[00:00:02.939,697] <err> modem_antenna: Failed to set configuration (err: 65536)
[00:00:02.954,833] <err> modem_antenna: Failed to set configuration (err: 65536)
```

Manual AT command testing confirms RFFE commands are not supported:
```
AT%XMIPIRFFEDEV? → Error 65536
AT%XMIPIRFFE? → Error 65536
AT%XMIPIRFFECTRL=1,0,1,0,1 → Error 65536
AT%XRFTEST? → Error 65536
```

Modem otherwise functions correctly:
- Basic AT commands work (AT, AT+CGMI, etc.)
- SIM card detected and powered (IMSI: 222013423872426)
- Modem enters full functionality mode (CFUN=1) successfully
- No cellular signal: CSQ returns 99,99 (no signal detected)

## Comparison with Nordic Reference Design
I noticed the Thingy:91 X (PCA20035) with nRF9151 successfully uses RFFE commands in its configuration:

From `/home/nrf/boards/nordic/thingy91x/Kconfig.defconfig.nrf9151`:
```kconfig
config MODEM_ANTENNA_AT_MIPIRFFEDEV
    default "AT%XMIPIRFFEDEV=1,4,71,198,248"
config MODEM_ANTENNA_AT_MIPIRFFECTRL_INIT
    default "AT%XMIPIRFFECTRL=1,0,1,28,248"
config MODEM_ANTENNA_AT_MIPIRFFECTRL_ON
    default "AT%XMIPIRFFECTRL=1,1,1,28,56,13,0,0,8,8,715,4,4,770,12,12,829..."
```

This confirms that nRF9151 SHOULD support RFFE commands for antenna switch control.

## Questions

1. **Does modem firmware 2.0.2 support RFFE 2.1 commands?**
   - If not, which firmware version first introduced RFFE support?
   - Is there a firmware update roadmap for RFFE support on nRF9151?

2. **How does the Thingy:91 X control its antenna switch with nRF9151?**
   - Does it use a different modem firmware version?
   - Are there any special modem configuration steps required?

3. **Is there an alternative method to control RFFE devices on nRF9151?**
   - Can MAGPIO be used as a fallback for antenna switching?
   - Are there any undocumented AT commands for RF path control?

4. **What is the recommended approach for antenna switching on nRF9151?**
   - Should I use RFFE-controlled switches (QM13345)?
   - Or should I use GPIO-controlled switches (SKY13453, PE42423)?

## Additional Information

I've tested both production firmware 2.0.2 and production test firmware 2.3.8:
- **2.0.2**: RFFE commands fail with error 65536
- **2.3.8**: PTI firmware blocks most AT commands (restricted mode for factory testing)

The hardware design follows the QM13345 datasheet requirements:
- RFFE 2.1 interface properly connected
- VIO decoupling capacitor present
- Proper grounding
- ID pin configured for USID=0x7 (GND connection)

## Expected Outcome
I need to successfully control the QM13345 antenna switch to route RF signals from the nRF9151 modem (RFC) to the main antenna (RF1 port). This is blocking cellular connectivity testing.

## Request
Please provide:
1. Confirmation of RFFE support status in nRF9151 firmware versions
2. Recommended firmware version for RFFE-controlled antenna switches
3. Example configuration or AT command sequence for QM13345 control
4. Timeline for RFFE support if not currently available

## Attachments

- Full RTT log showing RFFE command failures
- Hardware schematic (relevant RFFE section)
- prj.conf configuration file

Thank you for your assistance.
(Connection lost)
00> [00:00:00.397,033] <inf> LSM6DSO: Initialize device lsm6dso@6b
00> [00:00:00.404,602] <inf> LSM6DSO: chip id 0x6a
00> [00:00:00.409,973] <err> nt3h2111: I2C read failed: -5
00> [00:00:00.416,168] <err> nt3h2111: Failed to read configuration: -5
00> [00:00:00.423,522] <wrn> nt3h2111: NT3H2111 may not be physically connected, continuing with defaults
00> [00:00:00.439,453] <inf> veml6030: VEML6030 initialized successfully
00> *** Booting My Application v1.0.0-704e3ba7cb7b ***
00> *** Using nRF Connect SDK v3.0.2-89ba1294ac9b ***
00> *** Using Zephyr OS v4.0.99-f791c49f492c ***
00> [00:00:00.460,021] <inf> main_app: Starting Multi-Sensor IoT Device Firmware
00> [00:00:00.467,895] <inf> main_app: Skipping config manager init for debugging
00> [00:00:00.475,860] <inf> main_app: Data transmission interval set to 60 seconds
00> [00:00:00.484,039] <inf> battery_monitor: Battery monitor initialized (LTC4060 charger)
00> [00:00:00.492,919] <inf> main_app: Battery m[00:00:02.648,162] <inf> main_app: Calling nrf_modem_lib_init()...
00> [00:00:02.902,191] <err> modem_antenna: Failed to set configuration (err: 65536)
00> [00:00:02.911,254] <err> modem_antenna: Failed to set configuration (err: 65536)
00> [00:00:02.926,391] <err> modem_antenna: Failed to set configuration (err: 65536)
00> [00:00:02.941,467] <err> modem_antenna: Failed to set configuration (err: 65536)
00> [00:00:02.956,573] <err> modem_antenna: Failed to set configuration (err: 65536)
00> [00:00:02.986,389] <inf> main_app: nrf_modem_lib_init() returned: 0
00> [00:00:02.993,469] <inf> main_app: Modem library initialized successfully
00> [00:00:03.001,098] <inf> main_app: Waiting for modem to be fully ready...
00> [00:00:13.008,728] <wrn> main_app: Modem ready timeout - proceeding anyway
00> [00:00:16.016,754] <inf> main_app: Testing AT interface (attempt 2)...
00> [00:00:16.030,456] <inf> main_app: Modem responding: OK
00> 
00> [00:00:16.036,651] <inf> main_app: Getting modem information...
00> [00:00:16.049,926] <wrn> main_app: Failed to get modem info (err=65536)
00> [00:00:16.064,147] <inf> main_app: Manufacturer: Nordic Semiconductor ASA
00> OK
00> 
00> [00:00:16.078,765] <inf> main_app: Modem firmware version: mfw_nrf91x1_2.0.2
00> OK
00> 
00> [00:00:16.087,219] <inf> main_app: === CHECKING RFFE COMMAND SUPPORT ===
00> [00:00:16.101,379] <wrn> main_app: XMIPIRFFEDEV not supported (err=65536)
00> [00:00:16.115,936] <wrn> main_app: XMIPIRFFE not supported (err=65536)
00> [00:00:16.130,218] <wrn> main_app: XRFTEST not supported (err=65536)
00> [00:00:16.144,317] <wrn> main_app: %XRFTEST not supported (err=65536)
00> [00:00:16.158,477] <wrn> main_app: %XMIPIRFFE not supported (err=65536)
00> [00:00:16.166,198] <inf> main_app: === END RFFE COMMAND CHECK ===
00> [00:00:16.173,095] <err> main_app: ====================================
00> [00:00:16.180,786] <err> main_app: CRITICAL HARDWARE ISSUE DETECTED!
00> [00:00:16.188,232] <err> main_app: ====================================
00> [00:00:16.195,953] <err> main_app: QM13345 antenna switch requires RFFE 2.1 protocol
00> [00:00:16.204,833] <err> main_app: nRF9151 modem firmware 2.0.2 does NOT support RFFE
00> [00:00:16.213,806] <err> main_app: Without RFFE, the antenna switch cannot be controlled
00> [00:00:16.223,052] <err> main_app: The switch may be in an undefined/OFF state
00> [00:00:16.231,384] <err> main_app: 
00> [00:00:16.235,839] <err> main_app: WORKAROUND ATTEMPT:
00> [00:00:16.242,004] <err> main_app: The QM13345 ID pin configuration may set a default state
00> [00:00:16.251,525] <err> main_app: Your board has ID pin connected to solder bridge SB1/SBI2
00> [00:00:16.261,138] <err> main_app: Check if the solder bridge routes to GND (USID=0x7)
00> [00:00:16.270,172] <err> main_app: ====================================
00> [00:00:16.284,301] <inf> main_app: CFUN state check succeeded: +CFUN: 0
00> OK
00> 
00> [00:00:16.292,297] <wrn> main_app: Modem is in offline/airplane mode - needs activation!
00> [00:00:16.301,544] <inf> main_app: Configuring cellular connection for Telnyx (APN: data00.telnyx)...
00> [00:00:16.311,676] <inf> main_app: Following Nordic forum recommended sequence...
00> [00:00:16.320,007] <inf> main_app: Step 1: Setting CFUN=0 to disable radio...
00> [00:00:16.365,478] <inf> main_app: Radio disabled: OK
00> 
00> [00:00:17.371,520] <inf> main_app: Step 2: Setting automatic operator selection (AT+COPS=0)...
00> [00:00:17.387,542] <inf> main_app: Operator selection set to automatic: OK
00> 
00> [00:00:17.395,446] <inf> main_app: Step 3: Setting system mode (LTE-M and NB-IoT)...
00> [00:00:17.410,705] <wrn> main_app: System mode config failed (err=65536)
00> [00:00:17.418,518] <inf> main_app: Step 4: Configuring Telnyx APN (data00.telnyx)...
00> [00:00:17.433,685] <inf> main_app: APN configured: OK
00> 
00> [00:00:17.439,666] <inf> main_app: Step 7: Activating modem (AT+CFUN=1)...
00> [00:00:17.447,387] <inf> main_app: No search commands active - safe to activate!
00> [00:00:17.500,762] <inf> main_app: CFUN=1 set successfully: OK
00> 
00> [00:00:17.507,568] <inf> main_app: Waiting for modem to stabilize...
00> [00:00:20.514,801] <inf> main_app: Verifying modem state...
00> [00:00:20.521,484] <inf> main_app: SUCCESS: Modem is in full functionality mode
00> [00:00:20.529,632] <inf> main_app: Enabling SIM card power supply...
00> [00:00:20.536,773] <inf> main_app: Forcing SIM card power enable...
00> [00:00:20.544,219] <inf> main_app: Network registration notifications enabled: OK
00> 
00> [00:00:20.553,283] <wrn> main_app: XSIM not supported (err=65536)
00> [00:00:20.560,455] <inf> main_app: Triggering SIM communication to enable power...
00> [00:00:20.569,274] <inf> main_app: IMSI read (forces SIM power): 222013423872426
00> OK
00> 
00> [00:00:20.579,040] <wrn> main_app: XICCID failed (err=65536)
00> [00:00:20.585,784] <inf> main_app: Ensuring modem is in full functionality mode...
00> [00:00:20.594,543] <inf> main_app: Current CFUN state: +CFUN: 1
00> OK
00> 
00> [00:00:20.601,806] <inf> main_app: Querying SIM status multiple times to ensure power...
00> [00:00:21.111,236] <inf> main_app: SIM status attempt 1: +CPIN: READY
00> OK
00> 
00> [00:00:21.119,049] <inf> main_app: SIM detected and powered!
00> [00:00:22.125,518] <inf> main_app: =====================================
00> [00:00:22.133,026] <inf> main_app: SIM POWER STATUS:
00> [00:00:22.138,763] <inf> main_app: =====================================
00> [00:00:22.146,270] <inf> main_app: IMPORTANT: Pin 19 (SIM_1V8) only outputs voltage during SIM communication!
00> [00:00:22.157,135] <inf> main_app: The voltage will appear when modem actively talks to SIM.
00> [00:00:22.166,473] <inf> main_app: RST showing -1.8V indicates partial SIM interface activation.
00> [00:00:22.176,147] <inf> main_app: Please measure NOW while firmware is running:
00> [00:00:22.184,387] <inf> main_app:   - SIM VCC (pin C1): Should show 1.8V during communication
00> [00:00:22.193,908] <inf> main_app:   - SIM RST (pin C2): -1.8V is normal (active low)
00> [00:00:22.202,575] <inf> main_app: =====================================
00> [00:00:22.710,510] <inf> main_app: SIM detection after power enable: +CPIN: READY
00> OK
00> 
00> [00:00:22.719,390] <inf> main_app: SUCCESS: SIM card detected and ready!
00> [00:00:22.726,928] <inf> main_app: ====================================
00> [00:00:22.734,344] <err> main_app: ANTENNA SWITCH ISSUE DETECTED!
00> [00:00:22.741,485] <inf> main_app: ====================================
00> [00:00:22.748,931] <err> main_app: QM13345 uses RFFE 2.1 protocol
00> [00:00:22.756,072] <err> main_app: nRF9151 firmware 2.0.2 does NOT support RFFE commands
00> [00:00:22.765,319] <err> main_app: The antenna switch cannot be properly controlled!
00> [00:00:22.774,200] <inf> main_app: Attempting workarounds...
00> [00:00:22.781,280] <wrn> main_app: XMIPIRFFEDEV failed (err=65536) - device may already be configured
00> [00:00:22.792,449] <wrn> main_app: XMIPIRFFECTRL INIT failed (err=65536)
00> [00:00:22.800,964] <wrn> main_app: XMIPIRFFECTRL ON failed (err=65536)
00> [00:00:22.809,448] <wrn> main_app: XMIPIRFFEDBG read failed (err=65536)
00> [00:00:22.818,115] <wrn> main_app: XANTCFG failed (err=65536)
00> [00:00:22.824,951] <inf> main_app: ====================================
00> [00:00:22.832,397] <err> main_app: RFFE Configuration FAILED - Commands Not Supported!
00> [00:00:22.841,430] <err> main_app: QM13345 antenna switch is NOT properly configured
00> [00:00:22.850,311] <inf> main_app: ====================================
00> [00:00:22.857,727] <inf> main_app: Attempting alternative antenna configuration methods...
00> [00:00:22.867,431] <wrn> main_app: MAGPIO not available (err=65536)
00> [00:00:22.875,335] <wrn> main_app: Cannot get antenna tuning (err=65536)
00> [00:00:22.883,148] <inf> main_app: ====================================
00> [00:00:22.890,594] <err> main_app: CRITICAL: HARDWARE INCOMPATIBILITY
00> [00:00:22.898,101] <err> main_app: ====================================
00> [00:00:22.905,792] <err> main_app: Problem: QM13345 antenna switch requires RFFE 2.1 protocol
00> [00:00:22.915,496] <err> main_app: Issue: nRF9151 firmware 2.0.2 does NOT support RFFE
00> [00:00:22.924,530] <err> main_app: Result: Antenna switch stuck in unknown/OFF state
00> [00:00:22.933,380] <err> main_app: 
00> [00:00:22.937,835] <err> main_app: POSSIBLE SOLUTIONS:
00> [00:00:22.944,030] <err> main_app: 1. Hardware modification: Bypass QM13345 (connect RFC to RF1 directly)
00> [00:00:22.954,772] <err> main_app: 2. Add pull-up resistor on V1 (pin 8) to force RF1 selection
00> [00:00:22.964,660] <err> main_app: 3. Wait for Nordic to release RFFE-enabled firmware
00> [00:00:22.973,693] <err> main_app: 4. Use external GPIO to control V1-V4 pins (requires PCB rework)
00> [00:00:22.983,917] <err> main_app: ====================================
00> [00:00:23.092,803] <inf> main_app: Checking RF test mode capabilities...
00> [00:00:23.100,982] <wrn> main_app: RF test mode not available (err=65536)
00> [00:00:23.109,252] <inf> main_app: Radio functionality: +CFUN: 1
00> OK
00> 
00> [00:00:23.116,607] <inf> main_app: Radio is enabled (CFUN=1)
00> [00:00:23.123,626] <inf> main_app: RF switch configuration attempts completed
00> [00:00:23.131,591] <inf> main_app: ====================================
00> [00:00:23.139,038] <inf> main_app: ====================================
00> [00:00:23.146,453] <inf> main_app: QUICK SIGNAL CHECK BEFORE ATTACHMENT
00> [00:00:23.153,869] <inf> main_app: ====================================
00> [00:00:23.161,743] <inf> main_app: Signal strength: +CSQ: 99,99
00> OK
00> 
00> [00:00:23.169,006] <wrn> main_app: NO SIGNAL DETECTED (CSQ: 99,99)
00> [00:00:23.176,239] <wrn> main_app: Check antenna connection!
00> [00:00:23.183,288] <inf> main_app: SIM status: +CPIN: READY
00> OK
00> 
00> [00:00:23.190,185] <inf> main_app: ====================================
00> [00:00:23.197,631] <inf> main_app: Step 8: Waiting for network attachment (AT+CGATT)...
00> [00:00:23.206,909] <inf> main_app: [Attempt 1/30] Not attached yet: +CGATT: 0
00> OK
00> 
(Connection lost)
 5305.prj.conf
Parents
  • I'm using MAGPIO exclusively and the CESQ is still 99,99,255,255. I am not sure why. I am using the sample applications from https://github.com/Conexiotechnologies/conexio-firmware-sdk/tree/main/samples/conexio_stratus and modifying it for my board.

    From what I'm seeing the COEX2 isn't being activated (pasted the pin diagram below):

    The GNSS IS working as long as LTE is off. LTE seems to block it.

    00> *** Booting nRF Connect SDK v3.0.2-89ba1294ac9b ***
    00> *** Using Zephyr OS v4.0.99-f791c49f492c ***
    00> [00:00:00.249,511] <inf> GNSS_sample: Stratus GNSS sample started
    00> [00:00:00.249,603] <inf> GNSS_sample: Configuring modem for LTE + GNSS operation...
    00> [00:00:02.520,446] <inf> GNSS_sample: Modem ready
    00> [00:00:02.520,874] <inf> GNSS_sample: Modem FW: mfw_nrf91x1_2.0.2
    00> OK
    00> 
    00> [00:00:02.521,392] <inf> GNSS_sample: IMEI: 359404233656629
    00> OK
    00> 
    00> [00:00:02.521,423] <inf> GNSS_sample: Configuring RF front-end for LTE + GNSS...
    00> [00:00:02.522,521] <wrn> GNSS_sample: RF power pin still low after drive-strength boost
    00> [00:00:02.522,552] <inf> GNSS_sample: Configuring QM13345 MIPI switch for LTE path
    00> [00:00:02.529,113] <wrn> GNSS_sample: QM13345 not found at USID 0x00 (65536), trying 0x0C
    00> [00:00:02.529,602] <err> GNSS_sample: Failed to register QM13345 switch: 65536
    00> [00:00:02.529,602] <wrn> GNSS_sample: Failed to configure MIPI switch: 65536
    00> [00:00:02.529,632] <inf> GNSS_sample: Programming MAGPIO and COEX0 for Stratus board
    00> [00:00:02.530,456] <inf> GNSS_sample: MAGPIO programmed: OK
    00> [00:00:02.531,005] <inf> GNSS_sample: COEX0 programmed: OK
    00> [00:00:02.531,005] <inf> GNSS_sample: Setting modem to CFUN=0...
    00> [00:00:03.565,490] <inf> GNSS_sample: Enabling LTE-M + GNSS mode...
    00> [00:00:03.572,387] <inf> GNSS_sample: Setting modem to full functionality mode (CFUN=1)...
    00> [00:00:03.610,748] <inf> GNSS_sample: Waiting for LTE network registration...
    00> [00:00:18.611,450] <inf> GNSS_sample: System mode: %XSYSTEMMODE: 1,0,1,0
    00> OK
    00> 
    00> [00:00:18.611,816] <inf> GNSS_sample: Functional mode: +CFUN: 1
    00> OK
    00> 
    00> [00:00:18.612,243] <inf> GNSS_sample: LTE Registration: +CEREG: 0,4
    00> OK
    00> 
    00> [00:00:18.612,640] <inf> GNSS_sample: GPRS attach: +CGATT: 0
    00> OK
    00> 
    00> [00:00:18.613,098] <inf> GNSS_sample: Signal quality: +CSQ: 99,99
    00> OK
    00> 
    00> [00:00:18.613,555] <inf> GNSS_sample: Extended signal quality: +CESQ: 99,99,255,255,255,255
    00> OK
    00> 

    Here is my main.c:

    /*
     * Copyright (c) 2024-2025 Conexio Technologies, Inc
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     *
     * Enhanced GNSS Sample with proper modem configuration
     */
    
    #include <stdio.h>
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/drivers/gpio.h>
    #include <modem/nrf_modem_lib.h>
    #include <modem/lte_lc.h>
    #include <dk_buttons_and_leds.h>
    #include <nrf_modem_at.h>
    #include <nrf_modem_gnss.h>
    #include <math.h>
    #include <string.h>
    #include <hal/nrf_gpio.h>
    
    LOG_MODULE_REGISTER(GNSS_sample, LOG_LEVEL_INF);
    
    /* RF Front-end GPIO definitions */
    #define RF_PWR_GPIO_DEV		DT_NODELABEL(gpio0)
    #define RF_PWR_ENABLE_PIN	22  /* P0.22 -> RFFE_LTE_ENABLE / COEX2 net */
    #define GPS_ENABLE_PIN		19  /* P0.19 -> GPS_EN, low selects LTE path */
    
    /* LED definitions */
    #define GNSS_SEARCHING_LED	DK_LED1
    #define GNSS_FIX_LED		DK_LED2
    #define GNSS_BLOCKED_LED	DK_LED3
    #define ERROR_LED		DK_LED4
    
    /* Button definitions */
    #define START_GNSS_BTN		DK_BTN1_MSK
    #define STOP_GNSS_BTN		DK_BTN2_MSK
    
    /* Define the PVT data frame variable */
    static struct nrf_modem_gnss_pvt_data_frame pvt_data;
    
    /* Declare helper variables to find the TTFF */
    static int64_t gnss_start_time;
    static bool first_fix = false;
    
    static K_SEM_DEFINE(gnss_fix_sem, 0, 1);
    
    /* LTE event handler - simplified version */
    static void lte_handler(const struct lte_lc_evt *evt)
    {
    	if (!evt) {
    		return;
    	}
    
    	switch (evt->type) {
    	case LTE_LC_EVT_NW_REG_STATUS:
    		LOG_INF("CEREG status: %d", evt->nw_reg_status);
    		if (evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME || 
    		    evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_ROAMING) {
    			LOG_INF("LTE network registered!");
    		}
    		break;
    	case LTE_LC_EVT_LTE_MODE_UPDATE:
    		LOG_INF("LTE mode update: %d", evt->lte_mode);
    		break;
    	case LTE_LC_EVT_RRC_UPDATE:
    		LOG_INF("RRC %s",
    			evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ? "connected" : "idle");
    		break;
    	default:
    		LOG_DBG("Unhandled LTE event: %d", evt->type);
    		break;
    	}
    }
    
    /* RF Front-end configuration functions */
    static int configure_rf_front_end(void)
    {
    	int err;
    	const struct device *gpio_dev = DEVICE_DT_GET(RF_PWR_GPIO_DEV);
    
    	LOG_INF("Configuring RF front-end for LTE + GNSS...");
    
    	if (!device_is_ready(gpio_dev)) {
    		LOG_ERR("GPIO0 device not ready");
    		return -ENODEV;
    	}
    
    	/* Configure RF power enable pin (COEX2) */
    	err = gpio_pin_configure(gpio_dev, RF_PWR_ENABLE_PIN, 
    				 GPIO_OUTPUT_LOW | GPIO_PUSH_PULL | GPIO_ACTIVE_HIGH);
    	if (err) {
    		LOG_ERR("Failed to configure RF power pin: %d", err);
    		return err;
    	}
    
    	/* Configure GPS enable pin for antenna switching */
    	err = gpio_pin_configure(gpio_dev, GPS_ENABLE_PIN, 
    				 GPIO_OUTPUT_LOW | GPIO_PUSH_PULL | GPIO_ACTIVE_HIGH);
    	if (err) {
    		LOG_ERR("Failed to configure GPS_EN pin: %d", err);
    		return err;
    	}
    
    	/* Boost drive strength for COEX2 pin using Nordic HAL - exact match to working diagnostics */
    	nrf_gpio_pin_drive_t drive = NRF_GPIO_PIN_H0H1;
    	nrf_gpio_reconfigure(NRF_GPIO_PIN_MAP(0, RF_PWR_ENABLE_PIN), NULL, NULL, NULL, &drive, NULL);
    
    	/* Enable RF power, set GPS_EN low for LTE path initially - exact sequence */
    	gpio_pin_set(gpio_dev, RF_PWR_ENABLE_PIN, 1);
    	k_sleep(K_MSEC(1));  /* Let the power rail settle */
    
    	/* Verify COEX2 is high - exact same check as working diagnostics */
    	if (!gpio_pin_get(gpio_dev, RF_PWR_ENABLE_PIN)) {
    		LOG_WRN("RF power pin still low after drive-strength boost");
    	} else {
    		LOG_INF("RF power switch asserted, GPS_EN held low");
    	}
    
    	/* Explicitly set GPS_EN low after RF power is on */
    	gpio_pin_set(gpio_dev, GPS_ENABLE_PIN, 0);
    
    	return 0;
    }
    
    static int configure_qm13345_switch(void)
    {
    	int err;
    	char response[64];
    
    	LOG_INF("Configuring QM13345 MIPI switch for LTE path");
    
    	/* Try to register QM13345 at USID 0x00 first - matching working lte_diagnostics */
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT%%XMIPIRFFEDEV=0,0");
    	if (err) {
    		LOG_WRN("QM13345 not found at USID 0x00 (%d), trying 0x0C", err);
    		err = nrf_modem_at_cmd(response, sizeof(response), "AT%%XMIPIRFFEDEV=0,12");
    		if (err) {
    			LOG_ERR("Failed to register QM13345 switch: %d", err);
    			return err;
    		}
    	}
    
    	/* Configure switch for LTE path */
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT%%XMIPIRFFECTRL=0,0,1,0x1C,0x01");
    	if (err) {
    		LOG_ERR("Failed to configure QM13345 INIT phase: %d", err);
    		return err;
    	}
    
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT%%XMIPIRFFECTRL=0,1,1,0x1C,0x01");
    	if (err) {
    		LOG_ERR("Failed to configure QM13345 ON phase: %d", err);
    		return err;
    	}
    
    	LOG_INF("QM13345 switch locked to RF1");
    	return 0;
    }
    
    static int configure_magpio_and_coex(void)
    {
    	int err;
    	char response[128];
    
    	LOG_INF("Programming MAGPIO and COEX0 for Stratus board");
    
    	/* Configure MAGPIO for LTE bands */
    	err = nrf_modem_at_cmd(response, sizeof(response),
    		"AT%%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,"
    		"4,880,960,5,791,849,7,1565,1586");
    	if (err) {
    		LOG_ERR("MAGPIO programming failed: %d", err);
    		return err;
    	}
    	LOG_INF("MAGPIO programmed: OK");
    
    	/* Configure COEX0 for GNSS coexistence */
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT%%XCOEX0=1,1,1565,1586");
    	if (err) {
    		LOG_ERR("COEX0 programming failed: %d", err);
    		return err;
    	}
    	LOG_INF("COEX0 programmed: OK");
    
    	return 0;
    }
    
    
    /**
     * @brief Configure modem for LTE + GNSS operation with proper RF front-end setup
     */
    static int modem_configure_for_lte_gnss(void)
    {
    	int err;
    	char response[64];
    
    	LOG_INF("Configuring modem for LTE + GNSS operation...");
    
    	/* Initialize modem library first */
    	err = nrf_modem_lib_init();
    	if (err) {
    		if (err == -EALREADY) {
    			LOG_INF("Modem already initialized");
    		} else {
    			LOG_ERR("Failed to initialize modem library: %d", err);
    			return err;
    		}
    	}
    
    	/* Wait for modem to be ready */
    	k_sleep(K_SECONDS(2));
    
    	/* Test modem communication */
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT");
    	if (err) {
    		LOG_ERR("Modem not responding: %d", err);
    		return err;
    	}
    	LOG_INF("Modem ready");
    
    	/* Get modem info */
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CGMR");
    	if (err == 0) {
    		LOG_INF("Modem FW: %s", response);
    	}
    
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CGSN");
    	if (err == 0) {
    		LOG_INF("IMEI: %s", response);
    	}
    
    	/* Now configure the RF front-end */
    	err = configure_rf_front_end();
    	if (err) {
    		LOG_ERR("Failed to configure RF front-end: %d", err);
    		return err;
    	}
    
    	/* Configure QM13345 MIPI switch */
    	err = configure_qm13345_switch();
    	if (err) {
    		LOG_WRN("Failed to configure MIPI switch: %d", err);
    		/* Continue without MIPI switch - might not be present */
    	}
    
    	/* Configure MAGPIO and COEX0 */
    	err = configure_magpio_and_coex();
    	if (err) {
    		LOG_WRN("Failed to configure antenna settings: %d", err);
    		/* Continue without antenna configuration - will use defaults */
    	}
    
    	/* Turn off modem to change system mode */
    	LOG_INF("Setting modem to CFUN=0...");
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CFUN=0");
    	if (err) {
    		LOG_WRN("CFUN=0 request failed: %d", err);
    		/* Continue anyway - modem might already be in correct state */
    	}
    	k_sleep(K_SECONDS(1));
    
    	/* Enable LTE-M + GNSS in system mode (1,0,1,0) */
    	LOG_INF("Enabling LTE-M + GNSS mode...");
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT%%XSYSTEMMODE=1,0,1,0");
    	if (err) {
    		LOG_ERR("Failed to set system mode: %d", err);
    		return err;
    	}
    
    	/* Set modem to full functionality mode with LTE enabled (CFUN=1) */
    	LOG_INF("Setting modem to full functionality mode (CFUN=1)...");
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CFUN=1");
    	if (err) {
    		LOG_ERR("Failed to set CFUN=1: %d", err);
    		return err;
    	}
    
    	/* Wait for modem to connect to network automatically */
    	LOG_INF("Waiting for LTE network registration...");
    	k_sleep(K_SECONDS(15));
    
    	/* Verify configuration */
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT%%XSYSTEMMODE?");
    	if (err == 0) {
    		LOG_INF("System mode: %s", response);
    	}
    
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CFUN?");
    	if (err == 0) {
    		LOG_INF("Functional mode: %s", response);
    	}
    
    	/* Check LTE registration status and signal quality */
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CEREG?");
    	if (err == 0) {
    		LOG_INF("LTE Registration: %s", response);
    	}
    
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CGATT?");
    	if (err == 0) {
    		LOG_INF("GPRS attach: %s", response);
    	}
    
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CSQ");
    	if (err == 0) {
    		LOG_INF("Signal quality: %s", response);
    	}
    
    	err = nrf_modem_at_cmd(response, sizeof(response), "AT+CESQ");
    	if (err == 0) {
    		LOG_INF("Extended signal quality: %s", response);
    	}
    
    	return 0;
    }
    
    static int modem_init(void)
    {
    	/* Modem initialization is now handled in modem_configure_for_lte_gnss() */
    	return 0;
    }
    
    /* Define a function to log fix data in a readable format */
    static void print_fix_data(struct nrf_modem_gnss_pvt_data_frame *pvt_data)
    {
    	LOG_INF("===========================================");
    	LOG_INF("           GPS POSITION ACQUIRED          ");
    	LOG_INF("===========================================");
    	LOG_INF("Latitude:       %.06f°", pvt_data->latitude);
    	LOG_INF("Longitude:      %.06f°", pvt_data->longitude);
    	LOG_INF("Altitude:       %.01f m", pvt_data->altitude);
    	LOG_INF("Accuracy:       %.01f m", pvt_data->accuracy);
    	LOG_INF("Speed:          %.01f m/s", pvt_data->speed);
    	LOG_INF("Heading:        %.01f°", pvt_data->heading);
    	LOG_INF("Time (UTC):     %04u-%02u-%02u %02u:%02u:%02u.%03u",
    	       pvt_data->datetime.year,
    	       pvt_data->datetime.month,
    	       pvt_data->datetime.day,
    	       pvt_data->datetime.hour,
    	       pvt_data->datetime.minute,
    	       pvt_data->datetime.seconds,
    	       pvt_data->datetime.ms);
    	LOG_INF("Google Maps:    https://maps.google.com/?q=%.6f,%.6f",
    	       pvt_data->latitude, pvt_data->longitude);
    	LOG_INF("===========================================");
    }
    
    static void gnss_event_handler(int event)
    {
    	int err;
    	static int satellites_tracked = 0;
    
    	switch (event) {
    	case NRF_MODEM_GNSS_EVT_PVT:
    		err = nrf_modem_gnss_read(&pvt_data, sizeof(pvt_data), NRF_MODEM_GNSS_DATA_PVT);
    		if (err) {
    			LOG_ERR("Failed to read PVT data: %d", err);
    			return;
    		}
    
    		/* Count satellites */
    		satellites_tracked = 0;
    		for (int i = 0; i < 12; i++) {
    			if (pvt_data.sv[i].signal != 0) {
    				satellites_tracked++;
    			}
    		}
    
    		if (pvt_data.flags & NRF_MODEM_GNSS_PVT_FLAG_FIX_VALID) {
    			/* Fix acquired! */
    			dk_set_led_off(GNSS_SEARCHING_LED);
    			dk_set_led_on(GNSS_FIX_LED);
    
    			print_fix_data(&pvt_data);
    
    			/* Print time to first fix */
    			if (!first_fix) {
    				LOG_INF("Time to first fix: %lld seconds",
    					(k_uptime_get() - gnss_start_time) / 1000);
    				first_fix = true;
    			}
    
    			k_sem_give(&gnss_fix_sem);
    		} else {
    			/* No fix yet */
    			dk_set_led_on(GNSS_SEARCHING_LED);
    			dk_set_led_off(GNSS_FIX_LED);
    
    			LOG_INF("GNSS: Searching for fix... (Satellites tracked: %d)",
    				satellites_tracked);
    		}
    		break;
    
    	case NRF_MODEM_GNSS_EVT_FIX:
    		LOG_INF("GNSS: Fix event");
    		break;
    
    	case NRF_MODEM_GNSS_EVT_AGNSS_REQ:
    		LOG_WRN("GNSS: A-GNSS data requested");
    		break;
    
    	case NRF_MODEM_GNSS_EVT_BLOCKED:
    		LOG_WRN("GNSS: Blocked by LTE");
    		dk_set_led_on(GNSS_BLOCKED_LED);
    		break;
    
    	case NRF_MODEM_GNSS_EVT_UNBLOCKED:
    		LOG_INF("GNSS: Unblocked");
    		dk_set_led_off(GNSS_BLOCKED_LED);
    		break;
    
    	case NRF_MODEM_GNSS_EVT_PERIODIC_WAKEUP:
    		LOG_DBG("GNSS: Periodic wakeup");
    		break;
    
    	case NRF_MODEM_GNSS_EVT_SLEEP_AFTER_FIX:
    		LOG_INF("GNSS: Sleep after fix");
    		break;
    
    	case NRF_MODEM_GNSS_EVT_SLEEP_AFTER_TIMEOUT:
    		LOG_WRN("GNSS: Sleep after timeout - no fix");
    		break;
    
    	default:
    		LOG_DBG("GNSS: Unknown event %d", event);
    		break;
    	}
    }
    
    int main(void)
    {
    	int err;
    	
    	LOG_INF("Stratus GNSS sample started");
    
    	if (dk_leds_init() != 0) {
    		LOG_ERR("Failed to initialize the LEDs Library");
    	}
    
    	/* Simple GPIO test first to verify pin driving */
    	err = configure_rf_front_end();
    	if (err) {
    		LOG_ERR("Failed to configure RF front-end: %d", err);
    		return 0;
    	}
    
    	/* Test GPIO toggling to verify pin is working */
    	const struct device *gpio_dev = DEVICE_DT_GET(RF_PWR_GPIO_DEV);
    	LOG_INF("Testing GPIO pin toggling...");
    	for (int i = 0; i < 5; i++) {
    		gpio_pin_set(gpio_dev, RF_PWR_ENABLE_PIN, 1);
    		LOG_INF("Pin %d set HIGH, reading: %d", RF_PWR_ENABLE_PIN, gpio_pin_get(gpio_dev, RF_PWR_ENABLE_PIN));
    		k_sleep(K_SECONDS(2));
    		
    		gpio_pin_set(gpio_dev, RF_PWR_ENABLE_PIN, 0);
    		LOG_INF("Pin %d set LOW, reading: %d", RF_PWR_ENABLE_PIN, gpio_pin_get(gpio_dev, RF_PWR_ENABLE_PIN));
    		k_sleep(K_SECONDS(2));
    	}
    
    	/* Leave pin high for modem test */
    	gpio_pin_set(gpio_dev, RF_PWR_ENABLE_PIN, 1);
    	LOG_INF("Pin %d left HIGH for modem test, reading: %d", RF_PWR_ENABLE_PIN, gpio_pin_get(gpio_dev, RF_PWR_ENABLE_PIN));
    	k_sleep(K_SECONDS(3));
    
    	err = modem_configure_for_lte_gnss();
    	if (err) {
    		LOG_ERR("Failed to configure modem for LTE + GNSS");
    		return 0;
    	}
    
    	/* Wait for LTE connection to establish before starting GNSS */
    	LOG_INF("LTE + GNSS mode activated, waiting for LTE connection...");
    	k_sleep(K_SECONDS(10));
    
    	/* Register the GNSS event handler */
    	if (nrf_modem_gnss_event_handler_set(gnss_event_handler) != 0) {
    		LOG_ERR("Failed to set GNSS event handler");
    		return 0;
    	}
    
    	/* Set the GNSS fix interval and GNSS fix retry period */
    	if (nrf_modem_gnss_fix_interval_set(CONFIG_GNSS_PERIODIC_INTERVAL) != 0) {
    		LOG_ERR("Failed to set GNSS fix interval");
    		return 0;
    	}
    
    	if (nrf_modem_gnss_fix_retry_set(CONFIG_GNSS_PERIODIC_TIMEOUT) != 0) {
    		LOG_ERR("Failed to set GNSS fix retry");
    		return 0;
    	}
    
    	/* Set GNSS to highest priority mode */
    	if (nrf_modem_gnss_prio_mode_enable() != 0) {
    		LOG_WRN("Failed to enable GNSS priority mode, continuing anyway");
    	} else {
    		LOG_INF("GNSS priority mode enabled");
    	}
    
    	/* Start the GNSS receiver */
    	LOG_INF("Starting GNSS");
    	if (nrf_modem_gnss_start() != 0) {
    		LOG_ERR("Failed to start GNSS");
    		return 0;
    	}
    
    	/* Log the current system uptime */
    	gnss_start_time = k_uptime_get();
    
    	return 0;
    }
    

    And the pin diagram:

    I have a feeling it might just be a software issue I'm not seeing.

  • Hello,

    mystic said:
    I am using the sample applications from https://github.com/Conexiotechnologies/conexio-firmware-sdk/tree/main/samples/conexio_stratus and modifying it for my board.

    Can you please provide a full board layout for your custom IoT device? Please provide both schematics and layout. 

    mystic said:
    I'm using MAGPIO exclusively and the CESQ is still 99,99,255,255

    What antenna are you using in your design? The signal quality seems very low or non-existent. 

    mystic said:
    The GNSS IS working as long as LTE is off. LTE seems to block it.

    Yes, this is correct. From nRF9151 Datasheet GPS receiver - GPS receiver operation is time multiplexed with the LTE modem, and GPS and QZSS position can be received while the LTE modem is in RRC Idle mode, power saving mode (PSM), or completely deactivated.

    Kind regards,
    Øyvind

Reply Children
Related