SPI Sleep Power too high

Hi Nordic Community

I am struggling to understand how to lower my sleep power consumption for SPI.

I am using the nRF52840DK and I have connected a Waveshare eInk screen (gdew042t2) using SPI. I have also connected a DS3231 RTC as well as a SHT31 thermometer via I2C.

I am using nRF Connect SDK v2.0.0.

Everything works, but when I monitor power usage, the chip is always drawing around 2mA of power, even when sleeping. 

In my investigations I think I have narrowed down the power draw to the eInk screen.

created a very basic project based off the Blinky app to test this. I set the project to blink twice and then permanently sleep. I added in the standard Power Management features (prj.conf adds CONFIG_PM=y CONFIG_PM_DEVICE=y CONFIG_SERIAL=n) and (main.c adds #include <pm/pm.h> #include <pm/device.h>).

1) I only add SPI to the project by adding CONFIG_SPI=y to prj.conf. 

The power draw of the device when sleeping is around 5mA. If I pull out the CS pin connecting the screen to the DK the power usage instantly drops to ~4µA which is what I expect for a sleeping DK. I have a PPK logic port attached to the CS pin and I can see it showing HIGH when plugged in and LOW when physically pulled out.

2) I add in more code to add the screen to the project. I add CONFIG_HEAP_MEM_POOL_SIZE=16384, CONFIG_MAIN_STACK_SIZE=2048, CONFIG_DISPLAY=y and CONFIG_GD7965=y to prj.conf). I also add set(SHIELD waveshare_epaper_gdew042t2) to CMakeLists.txt.

The power draw of the device when sleeping is now around 2mA (same as my full project). If I pull out the CS pin connecting the screen to the DK the power usage stays the same. The PPK logic port attached to the CS pin stays HIGH. If I disconnect all the Pins to the screen then the power usage drops to ~600µA.

The drivers for the screen use the arduino_spi devicetree bindings. I am not sure if this is relevant but the SCK, MISO and MOSI Pins are specified in the  DTSI file in both the "default" and "sleep" groups but the CS PIN is specified in the main DTS file and not mentioned in the DTSI "default" and  "sleep" groups.

Is there a specific way to put SPI to sleep that I am not aware of?

I am hoping you can point me in the right direction to try and reduce the power usage.

Here are some of the relevant settings:

waveshare_epaper_gdew042t2.overlay

#include "waveshare_epaper_common.dtsi"

/ {
  chosen {
    zephyr,display = &gd7965;
  };
};

&arduino_spi {
  gd7965: gd7965@0 {
    compatible = "gooddisplay,gd7965","gooddisplay,gdew042t2";
    label = "GD7965";
    spi-max-frequency = <4000000>;
    reg = <0>;
    width = <400>;
    height = <300>;
    dc-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */
    reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */
    busy-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */
    pwr = [03 00 26 26 09];
    softstart = [17 17 17];
    cdi = <0xd7>;
    tcon = <0x22>;
  };
};

waveshare_epaper_common.dtsi

&arduino_spi {
  status = "okay";
  cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>, /* D10 */
                   <&arduino_header 12 GPIO_ACTIVE_LOW>; /* D04 */

  sdhc0: sdhc@1 {
    compatible = "zephyr,mmc-spi-slot";
    reg = <1>;
    status = "okay";
    label = "SDHC0";
    spi-max-frequency = <24000000>;
  };
};

nrf52840dk_nrf52840 (only showing the arduino_spi part)

arduino_spi: &spi3 {
  status = "okay";
  cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */
  pinctrl-0 = <&spi3_default>;
  pinctrl-1 = <&spi3_sleep>;
  pinctrl-names = "default", "sleep";
};

nrf52840dk_nrf52840-pinctrl.dtsi (only showing spi3)

spi3_default: spi3_default {
  group1 {
    psels = <NRF_PSEL(SPIM_SCK, 1, 15)>,
                <NRF_PSEL(SPIM_MISO, 1, 14)>,
                <NRF_PSEL(SPIM_MOSI, 1, 13)>;
    };
};

spi3_sleep: spi3_sleep {
  group1 {
    psels = <NRF_PSEL(SPIM_SCK, 1, 15)>,
                 <NRF_PSEL(SPIM_MISO, 1, 14)>,
                 <NRF_PSEL(SPIM_MOSI, 1, 13)>;
    low-power-enable;
  };
};

CMakeLists.txt

added the line

set(SHIELD waveshare_epaper_gdew042t2)
Parents
  • Hi

    I tested this on my end and could indeed see the same behavior. A few things that could cause this:

    • In SPIM3 on the nRF52840, you need to disable the peripheral through the ENABLE register to get the current down. TASKS_STOP alone does not work. This will be updated in future versions of the nrfx drivers.
    • It could also be erratum 89, but that should be taken care of in the driver already.
    • Finally, it could be possible that the driver implements polling of some kind, and that the CPU wakes up too often.

    Best regards,

    Simon

Reply
  • Hi

    I tested this on my end and could indeed see the same behavior. A few things that could cause this:

    • In SPIM3 on the nRF52840, you need to disable the peripheral through the ENABLE register to get the current down. TASKS_STOP alone does not work. This will be updated in future versions of the nrfx drivers.
    • It could also be erratum 89, but that should be taken care of in the driver already.
    • Finally, it could be possible that the driver implements polling of some kind, and that the CPU wakes up too often.

    Best regards,

    Simon

Children
  • Hi Simon

    Thanks for the guidance.

    I am very new to Nordic hardware and especially the Zephyr RTOS so this has been quite challenging.

    I'll work my way though your suggestions and see if I can make any difference to the power usage.

    My project updates the screen very infrequently (max once per minute) so I don't need to keep the screen immediately ready. Is there any way in Zephyr to force shut down of the device/screen or force disable SPI or disconnect all the relevant GPIO pins and then re-enable when I need to update? Nothing I have tried in the power management file has had any effect.

    Regards,

    Gary

Related