Hello CircuitDojo Community,

I am working on a Sparkfun Thing Plus nRF9160, developing firmware for a battery powered sensing device. Over the past day and half I have been searching for Nordic and other documentation on putting the nRF9160 SiP into its lower power and sleep modes. As I understand this part, the nRF9160 entails an LTE modem, a dedicated ARM processor to control the modem (provides AT command interpreter), and the larger ARM Cortex-M33 as developer’s application processor.

My first questions are:

(1) At a block diagram level is this “modem and two processors” description correct?
(2) To enter lower or lowest sleep modes need I turn off modem, modem processor, and app processor?

I have had some difficulty finding a diagram or description of Nordic’s nRF9160 sufficient to confirm that indeed there is some second, somewhat hidden processor to support the LTE modem. I observe however, when I have CONFIG_SERIAL=y in my prj.conf file, and am talking to the Sparkfun board serially, I can issue AT commands and turn on and turn off the modem. E.g. by issuing at+cfun=4, and at+cfun=1 and similar. When the modem is off, however, the AT command parser is still consuming UART0 input and responds to AT commands. So that processor that’s running firmware other than my own is itself yet powered and consuming current, though the LTE modem is off.

Because it has been as difficult to find example apps showing deep sleep entry and wake up for the nRF9160 and supported boards, I think I may not yet be asking the correct questions. This leads to my remaining questions:

(3) Exists there a more detailed document which identifies the modem’s dedicated processor in the nRF9160?
(4) Are there any sample apps available, which show how to put nRF9160 into deep sleep mode and wake up?

Thanks in advance for any help the community here can offer!

  • Ted

    tedhavelka66 you can check out the active_sleep sample in NFED where I turn some of the peripherals off by default. You can also set the UART to turn off RX during runtime as well using Zephyr’s power controls.

    CONFIG_PM_DEVICE=y
    /* Power off UART module */
    uart_rx_disable(uart_dev);
    k_sleep(K_MSEC(100));
    err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_OFF);
    if (err)
    {
        LOG_WRN("Can't power off uart: %d", err);
    }

    The power management API is your friend if the driver you’re using implements it. For Nordic’s stuff, I think most of the peripherals do have it setup.

    Good afternoon Jared,

    Thank you for the again quick reply! When you say “turn off some of the peripherals by default” refer you to these settings in a file named spm.conf? . . .

    Curious, for what is the ‘child image’ subdirectory so named? Also curious, for lowest power consuming modes in nRF9160 based designs, do I need to worry about powering down a second processor in the nRF9160 SiP?

    I’ll have much control over the application core, but I’m not finding clear information about the core or controller which executes the 9160 LTE modem AT command parser.

    Thank you again, Jared!

    • Ted

    Good question:

    You can disable the RX pin on a device “permanently” by deleting the RX pin in your overlay:

    For example:

    &uart2 {
    	status = "okay";
    	current-speed = <115200>;
    	tx-pin = <24>;
    	/delete-property/ rx-pin;
    };

    Or, if you want to use it during runtime, you can use the power management APIs I mentioned previously.

    Curious, for what is the ‘child image’ subdirectory so named? Also curious, for lowest power consuming modes in nRF9160 based designs, do I need to worry about powering down a second processor in the nRF9160 SiP?

    I believe that folder is used if you want to modify mcuboots config or the config for the SPM. I’ve used it previously to disable all serial output in the SPM so it doesn’t turn it on before initializing the application.

    4 days later

    Good evening Jared,

    Thank you for the guidance regarding UART disabling via DTS overlay files, and the example code above. I cloned the nfed code project from CircuitDojo’s public github repo at https://github.com/circuitdojo/nrf9160-feather-examples-and-drivers. Searching in active_sleep and then all the example apps there, I could not find any references to routines uart_rx_disable() nor pm_device_state_set().

    These two routines appear to be key in the code excerpt in your first reply in this thread.

    Upon git cloning the default branch I find is v1.7.x. I switched to main and searched those sources also. Did you mean to share code specifically from the active_sleep project you authored, or is the code sample from another context?

    Without seeing the larger code context, I wonder what purpose the line k_sleep(K_MSEC(100)); serves? If I disable the a given UART in my own app, when I go to re-enable the UART will I need a similar delay between calling uart_rx_enable() and a call to, I am guessing, pm_device_state_set(uart_dev, PM_DEVICE_STATE_RESUMING);?

    For development purposes I am looking to turn off and turn on UARTs via a simple CLI. I have a home authored command line interface working. My goal is to set up a timer which will turn off the UART which the CLI uses, for x number of seconds per user request. Then turns the UART on again.

    Given these run time goals, for now I’ll leave the overlay file intact, specifying TX and RX pin assignments for the UART.

    Thanks again. Your help has put me onto some useful Zephyr documentation, definitely speeding up the learning process here!

    • Ted

      tedhavelka66 Upon git cloning the default branch I find is v1.7.x. I switched to main and searched those sources also. Did you mean to share code specifically from the active_sleep project you authored, or is the code sample from another context?

      The samples are not in main they’re in 1.7.x (nfed/samples/active_sleep)

      tedhavelka66 Without seeing the larger code context, I wonder what purpose the line k_sleep(K_MSEC(100)); serves? If I disable the a given UART in my own app, when I go to re-enable the UART will I need a similar delay between calling uart_rx_enable() and a call to, I am guessing, pm_device_state_set(uart_dev, PM_DEVICE_STATE_RESUMING);?

      I haven’t tested whether or not it’s needed. I think this code is borrowed from Nordic (so it had a purpose). Sorry I don’t have a better explanation. As for resuming, I’m not sure. You’ll have to experiment.

      Good luck @tedhavelka66. Let me know how it goes!

      Good morning Jared,

      Sorry for the basic question, I’m looking at the lone source file in nrf9160-feather-examples-and-drivers/samples/active_sleep/src/
      main.c
      , and not finding the code which turns off a UART. Is this repository the one you are calling nfed?

      By the way, I did a full recursive pattern search for those power management routines, with grep at the top of the samples directory in repo ‘nrf9160-feather-examples-and-drivers’. I did so for both its release v1.7.x and the main branch. This should catch all instances of those routine calls, across all source files in all nfed projects. Unless I have cloned the incorrect repo.

      The code excerpt has been sufficient to get me going in a useful direction. Just asking one last time as I’m not seeing what you say is part of the active sleep project. Not perusing the source files on github itself, and not in more exhaustive searches of the cloned projects at home.

      • Ted

      Ahh sorry. That particular code is not in NFED at the moment.

      No worries - I am experimenting with ideas from your code excerpt above. I’ll write back if I get totally stuck. Thank you again Jared!

        Terms and Conditions | Privacy Policy