How to reduce the power consumption of the 9160‘s modem?

I am using 9160 to develop a customer's product, which needs to reduce power consumption as much as possible to prolong the battery life of the product. I know that 9160 communicates with the modem through the default UART0. My product design uses UART2 to communicate with a peripheral.  Setting UART2 to DEVICE_PM_LOW_POWER_STATE alone reduces the current by only about 30uA, whereas setting Uart0 to DEVICE_PM_LOW_POWER_STATE reduces the current by almost 500uA. What I can't understand is,  In fact, the GPIO pin mapped to UART0 is not connected to any line, why do you need to set the low power state to reduce power consumption?  

#define MODEM_DEV		"UART_0"
#define BLE_DEV			"UART_2"

	uart_ble = device_get_binding(BLE_DEV);
	if(!uart_ble)
	{
	#ifdef UART_DEBUG
		LOGD("Could not get %s device", BLE_DEV);
	#endif
		return;
	}

	uart_modem = device_get_binding(MODEM_DEV);
	if(!uart_modem)
	{
	#ifdef UART_DEBUG
		LOGD("Could not get %s device", uart_modem);
	#endif
		return;
	}
	
void uart_sleep_out(void)
{
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
	if(k_timer_remaining_get(&uart_sleep_in_timer) > 0)
		k_timer_stop(&uart_sleep_in_timer);
	k_timer_start(&uart_sleep_in_timer, K_SECONDS(UART_WAKE_HOLD_TIME_SEC), NULL);

	if(uart_is_waked)
		return;

#if 1	
	device_set_power_state(uart_ble, DEVICE_PM_ACTIVE_STATE, NULL, NULL);
	uart_irq_rx_enable(uart_ble);
	uart_irq_tx_enable(uart_ble);
	k_sleep(K_MSEC(10));
#else
	device_set_power_state(uart_modem, DEVICE_PM_ACTIVE_STATE, NULL, NULL);
	uart_irq_rx_enable(uart_modem);
	uart_irq_tx_enable(uart_modem);
	k_sleep(K_MSEC(10));
#endif	
	
	uart_is_waked = true;

#ifdef UART_DEBUG
	LOGD("uart set active success!");
#endif
#endif
}

void uart_sleep_in(void)
{
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
	if(!uart_is_waked)
		return;

#if 1	
	uart_irq_rx_disable(uart_ble);
	uart_irq_tx_disable(uart_ble);
	device_set_power_state(uart_ble, DEVICE_PM_LOW_POWER_STATE, NULL, NULL);
	k_sleep(K_MSEC(10));
#else
	uart_irq_rx_disable(uart_modem);
	uart_irq_tx_disable(uart_modem);
	device_set_power_state(uart_modem, DEVICE_PM_LOW_POWER_STATE, NULL, NULL);
	k_sleep(K_MSEC(10));
#endif
	
	uart_is_waked = false;

#ifdef UART_DEBUG
	LOGD("uart set low power success!");
#endif
#endif
}

  • Hello,

    duxinglang said:
    So it's log output using uart0, right?  But when I test, I find that even though I have log output turned off (CONFIG_LOG= N), if I don't set UART0 to DEVICE_PM_LOW_POWER_STATE, it still has around 600uA power consumption, why?  

    That depends as well on what your application is doing otherwise and which peripherals are enabled by default in your devicetree. Referring to the overlay-low-power.conf file of the Asset Tracker v2, which demonstrates how to disable logging over UART.

    And of course, the power consumption is depended on the modem state as well. If it is enabled, but not in PSM/eDRX, the current consumption will not decrease.

    duxinglang said:
    This setting can only be operated after the modem is set and the AT instruction is sent to connect to the network, otherwise the device will restart.  

    Yes, that makes sense! UART0 is required to forward the AT commands to the application, which then will forward them to the modem via the modem library interface. If UART0 is disabled or in low power state, this is not possible unless another UART peripheral is used instead.

    Regards,

    Markus

  • So, does this mean that 9160 still needs a uart to communicate with the modem?  Why can't the application call the relevant functions to communicate with the modem directly instead of sending AT instructions through the uart?  Does this mean that every time you use a modem, you have to use a uart, so you have at least 600uA power consumption?  

  • duxinglang said:
    So, does this mean that 9160 still needs a uart to communicate with the modem?

    The nRF9160 has two separate cores, an application and a modem core. The application and the modem communicate with each other via the modem library interface, as already mentioned. So, if the application core is in lower-power state but the modem core not, the current consumption can still be significant.

    duxinglang said:
    Why can't the application call the relevant functions to communicate with the modem directly instead of sending AT instructions through the uart?  Does this mean that every time you use a modem, you have to use a uart, so you have at least 600uA power consumption?  

    No. Basically, a UART peripheral is not needed for the application to send AT commands to the modem. But that implies that the application handles all necessary communication with the modem itself. If the application requires a certain extern user interface for handling AT commands, then a UART peripheral might be required.

    Regards,

    Markus

  • Thank you for your explanation!  If as you say, an application does not need the AT instruction to communicate with the modem, what are the interface functions that the application can use?  I checked the specifications and found that many modem operations are realized by sending AT instructions, such as the modem networking function w_lte_lc_init(). If no AT instructions are used, do these corresponding interface functions explain how to use them?  

  • duxinglang said:
    If no AT instructions are used, do these corresponding interface functions explain how to use them?  

    The communication between the modem and application is always based on AT commands. You can find a full overview and documentation of all the commands available here.

    duxinglang said:
    I checked the specifications and found that many modem operations are realized by sending AT instructions, such as the modem networking function w_lte_lc_init().

    The above mentioned function is part of the LTE link controller library, which is one of many that we are offering to improve user experience. They are basically a wrapper for AT commands, but in the end, those libraries use AT commands as well for direct communication with the modem. One example could be the system mode settings, which is called within the lte_lc_init() function.

    Regards,

    Markus

Related