External flash to sleep

My board (nrf52840 sense) has flash memory P25Q16H. When I put everything off, the board consumes 25uA. To save the last bit of current I would like to put the flash memory to deep sleep.

	spi_flash_dev = DEVICE_DT_GET(DT_ALIAS(spi_flash0));	
	if (!device_is_ready(spi_flash_dev)) {
		LOG_ERR("%s: device not ready.\n", spi_flash_dev->name);
		return ENODEV;
	}
	
	if(pm_device_action_run(spi_flash_dev, PM_DEVICE_ACTION_SUSPEND)) { //only consumes more power, 3mA ?!
		LOG_ERR("could not suspend qspi flash device %s", spi_flash_dev->name);
	}

In the debugger, eventually this function in file nrf_qspi_nor.c is executed:

#ifdef CONFIG_PM_DEVICE
static int enter_dpd(const struct device *const dev)
{
	if (IS_ENABLED(DT_INST_PROP(0, has_dpd))) {
		struct qspi_cmd cmd = {
			.op_code = SPI_NOR_CMD_DPD,
		};
		uint32_t t_enter_dpd = DT_INST_PROP_OR(0, t_enter_dpd, 0);
		int rc;

		rc = qspi_send_cmd(dev, &cmd, false);
		if (rc < 0) {
			return rc;
		}

		if (t_enter_dpd) {
			uint32_t t_enter_dpd_us =
				DIV_ROUND_UP(t_enter_dpd, NSEC_PER_USEC);

			k_busy_wait(t_enter_dpd_us);
		}
	}

	return 0;
}
#endif /* CONFIG_PM_DEVICE */

SPI_NOR_CMD_DPD is indeed to 0xB9, which is consistent with the datasheet.

Problem: after executing this command, the power rises to 3.94mA. I have no idea what is causing this.

I'm running zephyr 3.5.99 ncs 2.6.1

Parents
  • Hi,

    3.94mA could suggest that the CPU is prevented from entering sleep. Are you able to enable debug logging to see if there are any errors reported after calling pm_device_action_run()? 

    Best regards,

    Vidar

  • No, it resides in low power state, executes a K_SLEEP()

    cpu_idle.s

    	 * For all the other ARM architectures that do not implement BASEPRI,
    	 * PRIMASK is used as the interrupt locking mechanism, and it is not
    	 * necessary to set PRIMASK here, as PRIMASK would have already been
    	 * set by the caller as part of interrupt locking if necessary
    	 * (i.e. if the caller sets _kernel.idle).
    	 */
    #endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
    
    	/* Enter low power state */
    	_sleep_if_allowed wfi
    
    	/*
    	 * Clear PRIMASK and flush instruction buffer to immediately service
    	 * the wake-up interrupt.
    	 */
    	cpsie	i
    	isb
    
    	bx	lr

Reply
  • No, it resides in low power state, executes a K_SLEEP()

    cpu_idle.s

    	 * For all the other ARM architectures that do not implement BASEPRI,
    	 * PRIMASK is used as the interrupt locking mechanism, and it is not
    	 * necessary to set PRIMASK here, as PRIMASK would have already been
    	 * set by the caller as part of interrupt locking if necessary
    	 * (i.e. if the caller sets _kernel.idle).
    	 */
    #endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
    
    	/* Enter low power state */
    	_sleep_if_allowed wfi
    
    	/*
    	 * Clear PRIMASK and flush instruction buffer to immediately service
    	 * the wake-up interrupt.
    	 */
    	cpsie	i
    	isb
    
    	bx	lr

Children
Related