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.
I 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