LTE handler deregistered

Hi!

I am experiencing some odd behavior from the modem, and I hope you can help me understand it:

After I disconnect from LTE  using lte_lc_func_mode_set(LTE_LC_FUNC_MODE_DEACTIVATE_LTE), the lte_handler somehow get de-registered. When I try to turn LTE on later, I get notifications from the GNSS handler that it sometimes get blocked, but I get nothing from the LTE handler. 

When the NRF_MODEM_GNSS_EVT_PERIODIC_WAKEUP event gets called, I submit a thread to reconnect to LTE.

I have tried activating LTE with several different methods, both lte_lc_func_mode_set(LTE_LC_FUNC_MODE_ACTIVATE_LTE), lte_lc_connect_async(lte_handler) and  lte_lc_init_and_connect_async(lte_handler), but they all give the same result (Also tried with NULL argument, as the handler already is registered). 

I've even tried calling the full modem_init routine (as seen in different samples, including MAGPIO/COEX0 config, lte_lc_init, lte_lc_psm_req, lte_lc_connect_async(lte_handler)). The LTE handler does not react, and the thread is locked waiting for a semaphore that should be set in a LTE handler event.

Do you have any suggestions as to how I can get the LTE  handler back up?

Thank you for all your help!

Kind regards,

Torje

  • Hei Torje, 

    Do you have any suggestions as to how I can get the LTE  handler back up?

    Trying to reproduce the basic concept of your approach, I did not manage to succeed. I took the Hello World sample as a reference and added the following lines of code: 

    main.c 

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <modem/lte_lc.h>
    
    /* Semaphore used to block the main thread until the link controller has
     * established an LTE connection.
     */
    K_SEM_DEFINE(lte_connected, 0, 1);
    K_SEM_DEFINE(enter_psm, 0, 1);
    K_SEM_DEFINE(disable_lte, 0, 1);
    
    static void lte_handler(const struct lte_lc_evt *const evt)
    {
         switch (evt->type) {
         case LTE_LC_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)) {
    		
    			if(evt->nw_reg_status == LTE_LC_NW_REG_NOT_REGISTERED) {
    				printk("Network connection lost!\n");
    				k_sem_give(&disable_lte);
    			}
    			break;
    		}
    
    		printk("Connected to: %s network\n",
    		evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ? "home" : "roaming");
    
    		k_sem_give(&lte_connected);
    
    		break;
         case LTE_LC_EVT_PSM_UPDATE:
    		printk("Power Saving Mode negotiation completed!\nTracking Area Update interval: %ds, Active Time: %ds\n", evt->psm_cfg.tau, evt->psm_cfg.active_time);
    		break;
        case LTE_LC_EVT_MODEM_SLEEP_ENTER:
    		if(evt->modem_sleep.type == LTE_LC_MODEM_SLEEP_PSM) {
    			printk("Entering PSM. Good night!\n");
    			k_sem_give(&enter_psm);
    		}
    
    		break;
    	 case LTE_LC_EVT_EDRX_UPDATE:
         case LTE_LC_EVT_RRC_UPDATE:
         case LTE_LC_EVT_CELL_UPDATE:
         case LTE_LC_EVT_LTE_MODE_UPDATE:
         case LTE_LC_EVT_TAU_PRE_WARNING:
         case LTE_LC_EVT_NEIGHBOR_CELL_MEAS:
         case LTE_LC_EVT_MODEM_SLEEP_EXIT_PRE_WARNING:
         case LTE_LC_EVT_MODEM_SLEEP_EXIT:
                 /* Callback events carrying LTE link data */
                 break;
         default:
                 break;
         }
    }
    
    void main(void)
    {
    	int err;
    	enum lte_lc_func_mode func_mode;
    	enum lte_lc_system_mode sys_mode;
    	enum lte_lc_system_mode_preference sys_pref_mode;
    
    	printk("Hello World! %s\n", CONFIG_BOARD);
    
    	printk("Connecting to LTE network. This may take a few minutes...\n");
    
        err = lte_lc_init_and_connect_async(lte_handler);
        if (err) {
            printk("lte_lc_init_and_connect_async, error: %d\n", err);
            return;
        }
    
        k_sem_take(&lte_connected, K_FOREVER);
    
    	/* Check current system & functional modes */
    	err = lte_lc_system_mode_get(&sys_mode, &sys_pref_mode);
    	if(err) {
    		printk("Could not get modem system mode, error: %d\n", err);
    		return;
    	}
    	else {
    		printk("Current modem system mode: %d\n", sys_mode);
    		printk("Current modem preferred system mode: %d\n", sys_pref_mode);
    	}		
    	
    	err = lte_lc_func_mode_get(&func_mode);
    	if(err) {
    		printk("Could not get modem functional mode, error: %d\n", err);
    		return;
    	}
    	else {
    		printk("Current modem functional mode: %d\n", func_mode);
    	}
    
    	k_sem_take(&enter_psm, K_FOREVER);
    	printk("Waiting for 10s...\n");
    	k_msleep(10000);
    
    	/* Continue execution... */
    
    	/* Deactivate LTE services & cross-check new functional mode*/
    	err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_DEACTIVATE_LTE);
    	if(err) {
    		printk("Could not set modem functional mode, error: %d\n", err);
    		return;
    	}
    	err = lte_lc_func_mode_get(&func_mode);
    	if(err) {
    		printk("Could not get modem functional mode, error: %d\n", err);
    		return;
    	}
    	else {
    		printk("Current modem functional mode: %d\n", func_mode);
    	}	
    
    	k_sem_take(&disable_lte, K_FOREVER);
    	printk("Waiting for 10s...\n");
    	k_msleep(10000);
    
    	/* Re-activate LTE services & cross-check new functional mode*/
    	err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_ACTIVATE_LTE);
    	if(err) {
    		printk("Could not set modem functional mode, error: %d\n", err);
    		return;
    	}
    	err = lte_lc_func_mode_get(&func_mode);
    	if(err) {
    		printk("Could not get modem functional mode, error: %d\n", err);
    		return;
    	}
    	else {
    		printk("Current modem functional mode: %d\n", func_mode);
    	}	
    
    	while(1);	
    }

    prj.conf 

    # LTE link control
    CONFIG_LTE_LINK_CONTROL=y
    CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
    CONFIG_LTE_NETWORK_MODE_LTE_M_GPS=y
    ## Power saving timers.
    ### 320 hours PSM.
    CONFIG_LTE_PSM_REQ_RPTAU="11000001"
    ### 20 seconds active time.
    CONFIG_LTE_PSM_REQ_RAT="00001010"
    ## Enable notifications when modem enters PSM
    CONFIG_LTE_LC_MODEM_SLEEP_NOTIFICATIONS=y

    The output is as expected: 

    *** Booting Zephyr OS build v3.0.99-ncs1  ***
    Hello World! nrf9160dk_nrf9160
    Connecting to LTE network. This may take a few minutes...
    Connected to: home network
    Power Saving Mode negotiation completed!
    Tracking Area Update interval: 1152000s, Active Time: 20s
    Current modem system mode: 4
    Current modem preferred system mode: 0
    Current modem functional mode: 1
    Entering PSM. Good night!
    Waiting for 10s...
    Network connection lost!
    Current modem functional mode: 31
    Waiting for 10s...
    Current modem functional mode: 1
    Connected to: home network
    Entering PSM. Good night!

    I probably need more input since I might not have added all the functionality you are using. 

    Venleg helsing, 

    Markus 

Related