queries on qspi flash

Hello forum ,

                  here i m using nrf52840 customized board ;my flash is w25q64 i need to set my flash for deep power mode (sleep mode ) ;as well i need to set my supply gpio pins 5v and 3v3 ,backlight led gpio ,led gpio into sleep mode ; den i need to set pwm,adc,spi all into sleep mode ...pls sugest me for sleep mode because i need to measure current consumption during sleep mode for my board ...if possible pls send me sample code for sleep mode in overlay ...

Parents
  • Hello,

    Most examples should already be powered optimized if you add CONFIG_SERIAL=n. But you can find this useful:
    https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/test_and_optimize/optimizing/power.html 

    Kenneth

  • Hello kenneth,

                        pls help me sleep mode (power down ) using zephyr nrf52840 customised board  for PWM ,windbond qspi flash , adc ....i need to check current consumption during powerdown mode where i m using sdk 2.7.0

  • here i will upload my main.c where i tried to sleep mode for adc and pwm with terminal output 

    /*
     * Copyright (c) 2018 Jan Van Winkel <[email protected]>
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <inttypes.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/drivers/display.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/drivers/flash.h>
    #include <lvgl.h>
    #include <stdio.h>
    #include <string.h>
    #include <nrfx_qspi.h>
    #include <hal/nrf_qspi.h>
    #include <zephyr/kernel.h>
    #include <lvgl_input_device.h>
    #include <stdio.h>
    #include <zephyr/drivers/pwm.h>
    #include <zephyr/pm/device.h>
    
    // #include "Vtlogo565.h"
    // #include"Billirubino.h"
    // #include "Billirubin.h"
    #include <zephyr/drivers/adc.h>
    #include <zephyr/sys/util.h>
    #include <stdlib.h>
    #include <math.h>
    #include <zephyr/sys/poweroff.h>
    #include <zephyr/sys/reboot.h>
    
    #include "ui.h"
    #include "vars.h"
    #include "actions.h"
    #include "structs.h"
    #include "screens.h"
    
    using namespace eez;
    using namespace eez::flow;
    
    #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(app);
    static uint8_t sleepCount = 0;
    #define LED1_NODE DT_NODELABEL(led1)
    #define LED0_NODE DT_NODELABEL(led0)
    #define LED2_NODE DT_NODELABEL(led2)
    int16_t buf0, buf2, buf3;
    char *variable;
    lv_obj_t *main_screen;
    lv_obj_t *count_Value;
    uint16_t bilirubinValue = 0;
    char bilirubinValue_str[16];
    char PD1_str[16];
    char PD2_str[16];
    char pd_ratio_str[16];
    char battery_str[5];
    static bool offFlag = false;
    volatile bool adc_timeout = false;
    bool conversion_complete = false;
    bool display_timeout = false;
    
    #define PWM_FREQUENCY_HZ 4000U                          // Set frequency to 4 kHz
    #define PWM_PERIOD_NS (NSEC_PER_SEC / PWM_FREQUENCY_HZ) // 250,000 ns (250 µs)
    #define DUTY_CYCLE_PERCENT 70                           // Set duty cycle to 50%
    uint32_t pulse_width_ns = (PWM_PERIOD_NS * DUTY_CYCLE_PERCENT) / 100;
    
    #define FLASH_NODE DT_NODELABEL(w25q64)
    const struct device *flash_dev = DEVICE_DT_GET(FLASH_NODE);
    
    int32_t photodiode_one_mv = 0;
    int32_t photodiode_two_mv = 0;
    int32_t sum_photodiode_one = 0;
    int32_t sum_photodiode_two = 0;
    int32_t avg_photodiode_one = 0;
    int32_t avg_photodiode_two = 0;
    
    float phd1 = 0.0f;
    float phd2 = 0.0f;
    float value = 0.0f;
    // int32_t pd1_mv;
    int32_t pd2_mv;
    int32_t avg_pd1 = 0;
    int32_t avg_pd2 = 0;
    int battery_level = 0;
    float ratio = 0.0f;
    // char adc_ratio_str[32] = {0};
    static uint32_t battery_counter = 0;
    
    // #define CMD_READ_JEDEC_ID 0x9F
    #define CMD_POWER_DOWN    0xB9
    
    #if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
        !DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
    #error "No suitable devicetree overlay specified"
    #endif
    
    #define DT_SPEC_AND_COMMA(node_id, prop, idx) \
        ADC_DT_SPEC_GET_BY_IDX(node_id, idx),
    
    /* ADC channel configurations */
    static const struct adc_dt_spec adc_channels[] = {
        DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels, DT_SPEC_AND_COMMA)};
    
    struct adc_sequence sequence0 = {
        .buffer = &buf0,
        .buffer_size = sizeof(buf0),
    };
    
    struct adc_sequence sequence2 = {
        .buffer = &buf2,
        .buffer_size = sizeof(buf2),
    };
    
    struct adc_sequence sequence3 = {
        .buffer = &buf3,
        .buffer_size = sizeof(buf3),
    };
    bool stopFlag = false;
    int32_t volt = 0;
    volatile bool led2_on = false; // Flag to track if LED2 is on
    void EnterPowerdown();
    #ifdef CONFIG_GPIO
    static struct gpio_dt_spec button_gpio = GPIO_DT_SPEC_GET_OR(
        DT_ALIAS(sw1), gpios, {0}); // Button 1
    
    static struct gpio_callback button_callback;
    static struct gpio_dt_spec button_onoff = GPIO_DT_SPEC_GET_OR(DT_ALIAS(sw0), gpios, {0}); // Button 0 (e.g., ON/OFF)
    static struct gpio_callback button_onoff_callback;
    
    #endif
    
    static uint64_t last_activity_time = 0;
    static const uint32_t IDLE_TIMEOUT_MS = 40000; // 32 seconds
    
    #define LED_ON_DURATION_MS 200
    void led_timer_handler(struct k_timer *timer_id); // forward declaration
    K_TIMER_DEFINE(led_timer, led_timer_handler, NULL);
    
    #define ADC_DURATION_MS 10
    void adc_timer_handler(struct k_timer *timer_id); // forward declaration
    K_TIMER_DEFINE(adc_timer, adc_timer_handler, NULL);
    
    #define PWM_ON_DURATION_MS 200
    void pwm_timer_handler(struct k_timer *timer_id); // forward declaration
    K_TIMER_DEFINE(pwm_timer, pwm_timer_handler, NULL);
    
    #define DISPLAY_DURATION_MS 20000
    void display_timer_handler(struct k_timer *timer_id); // forward declaration
    K_TIMER_DEFINE(display_timer, display_timer_handler, NULL);
    
    uint64_t led2_on_timestamp = 0;
    uint64_t led2_off_timestamp = 0;
    // int32_t pd1_sum = 0, pd2_sum = 0;
    uint32_t sample_count = 0;
    
    static uint32_t count = 0;
    static uint32_t countbutton = 0;
    
    static bool led2_ever_used = false;
    static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_NODELABEL(ledbacklight), gpios);
    static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
    static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    static const struct gpio_dt_spec led2 = GPIO_DT_SPEC_GET(LED2_NODE, gpios);
    static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0));
    
    void updateGUI()
    {
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_BILIRUBIN_VALUE_STR, bilirubinValue_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_BILIRUBIN_LABEL, bilirubinValue_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_PD1, PD1_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_PD2, PD2_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_RATIO, pd_ratio_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_BATTERY_PERCENTAGE, battery_str);
    }
    
    void flash_power_down(void)
    {
        nrf_qspi_cinstr_conf_t cinstr_cfg = {
            .opcode    = CMD_POWER_DOWN,
            .length    = NRF_QSPI_CINSTR_LEN_1B, // Only 1 byte command
            .io2_level = true,
            .io3_level = true,
            .wipwait   = false,
            .wren      = false
        };
    
        nrfx_err_t err = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        if (err != NRFX_SUCCESS) {
            printk("Failed to send POWER-DOWN (B9h): %d\n", err);
        } else {
            printk("Flash entered deep power-down mode.\n");
        }
    }
    static void button_isr_callback(const struct device *port,
                                    struct gpio_callback *cb,
                                    uint32_t pins)
    {
        last_activity_time = k_uptime_get();
        int button_state = gpio_pin_get_dt(&button_gpio);
    
        if (button_state == 1)
        { // Button pressed
            gpio_pin_set_dt(&led2, 1);
            led2_on = true;
            // pd1_sum = 0;
            // pd2_sum = 0;
            k_timer_stop(&display_timer);
            display_timeout = false;
            sum_photodiode_one = 0;
            sum_photodiode_two = 0;
            sample_count = 0;
            led2_on_timestamp = k_uptime_get();
            k_timer_start(&led_timer, K_MSEC(LED_ON_DURATION_MS), K_NO_WAIT);
            k_timer_start(&adc_timer, K_MSEC(ADC_DURATION_MS), K_NO_WAIT);
            k_timer_start(&pwm_timer, K_MSEC(PWM_ON_DURATION_MS), K_NO_WAIT);
            printk("LED2 turned ON at %llu ms\n", led2_on_timestamp);
    
            int ret = pwm_set_dt(&pwm_led0, PWM_PERIOD_NS, pulse_width_ns);
            if (ret < 0)
            {
                printk("Failed to start PWM: %d\n", ret);
            }
            else
            {
                printk("PWM started with duty cycle %d ns\n", pulse_width_ns);
            }
    
            printk("LED2 turned ON at %llu ms\n", led2_on_timestamp);
        }
    
        else if (button_state == 0)
        { // Button released
            printk("Button released - stopping sampling\n");
            pwm_set_dt(&pwm_led0, 0, 0);
        }
    }
    
    static void button_onoff_handler(const struct device *dev,
                                     struct gpio_callback *cb,
                                     uint32_t pins)
    {
        // LOG_INF("Wake-up button pressed");
        // last_activity_time = k_uptime_get();
        // EnterPowerdown();
        offFlag = true;
        sleepCount = 0;
        countbutton = 0;
    }
    
    #ifdef CONFIG_LV_Z_ENCODER_INPUT
    static const struct device *lvgl_encoder =
        DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_encoder_input));
    #endif /* CONFIG_LV_Z_ENCODER_INPUT */
    
    #ifdef CONFIG_LV_Z_KEYPAD_INPUT
    static const struct device *lvgl_keypad =
        DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_keypad_input));
    #endif /* CONFIG_LV_Z_KEYPAD_INPUT */
    
    static void lv_btn_click_callback(lv_event_t *e)
    {
        ARG_UNUSED(e);
    
        count = 0;
    }
    
    void adc_timer_handler(struct k_timer *timer_id)
    {
        adc_timeout = true;
    }
    
    void display_timer_handler(struct k_timer *timer_id)
    {
        display_timeout = true;
    }
    
    void led_timer_handler(struct k_timer *timer_id)
    {
        conversion_complete = true;
    }
    
    void pwm_timer_handler(struct k_timer *timer_id)
    {
        int ret = pwm_set_dt(&pwm_led0, 0, 0); // Stop PWM
        if (ret < 0)
        {
            printk("Failed to stop PWM in timer: %d\n", ret);
        }
        else
        {
            printk("PWM stopped by timer\n");
        }
    }
    
    void PWMInit()
    {
        printk("pwminit");
        if (!pwm_is_ready_dt(&pwm_led0))
        {
            printk("Error: PWM device %s is not ready\n", pwm_led0.dev->name);
        }
    }
    
    void AdcInit()
    {
        printk("adcinit");
        for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++)
        {
            if (!device_is_ready(adc_channels[i].dev))
            {
                printk("ADC controller device not ready\n");
            }
    
            int err = adc_channel_setup_dt(&adc_channels[i]);
            if (err < 0)
            {
                printk("Could not setup channel #%d (%d)\n", i, err);
            }
        }
    }
    int calculate_battery_percentage(int32_t val_mv)
    {
        const int32_t FULL_CHARGE_MV = 2965; // Adjust based on your battery specs
        const int32_t EMPTY_CHARGE_MV = 1976;
    
        if (val_mv >= FULL_CHARGE_MV)
            return 100;
        if (val_mv <= EMPTY_CHARGE_MV)
            return 0;
    
        return (int)((val_mv - EMPTY_CHARGE_MV) * 100 / (FULL_CHARGE_MV - EMPTY_CHARGE_MV));
    }
    
    int32_t battery_adc()
    {
        int err;
    
        // Initialize ADC sequence for battery channel (channel 2)
        err = adc_sequence_init_dt(&adc_channels[2], &sequence3);
        if (err < 0)
        {
            printk("Failed to initialize ADC channel 2 sequence\n");
            return err;
        }
    
        err = adc_read(adc_channels[2].dev, &sequence3);
        if (err < 0)
        {
            printk("ADC read error on channel 2: %d\n", err);
            return err;
        }
    
        int32_t val_mv = buf3;
    
        err = adc_raw_to_millivolts_dt(&adc_channels[2], &val_mv);
        if (err < 0)
        {
            printk("Conversion error for channel 2\n");
            return err;
        }
    
        battery_level = calculate_battery_percentage(val_mv);
    
        printk("Battery: %" PRId32 " mV (%d%%)\n", val_mv, battery_level);
        snprintf(battery_str, sizeof(battery_str), "%d", battery_level);
        updateGUI();
    
        return val_mv; // If you want to return mV for display
    }
    
    int32_t adcRead()
    {
        int err;
    
        // Initialize ADC sequences for PD1 (channel 0) and PD2 (channel 1)
        err = adc_sequence_init_dt(&adc_channels[0], &sequence0);
        if (err < 0)
        {
            printk("Failed to initialize ADC channel 0 sequence\n");
            return err;
        }
    
        err = adc_sequence_init_dt(&adc_channels[1], &sequence2);
        if (err < 0)
        {
            printk("Failed to initialize ADC channel 1 sequence\n");
            return err;
        }
    
        // Read ADC values
        err = adc_read(adc_channels[0].dev, &sequence0);
        if (err < 0)
        {
            printk("ADC read error on channel 0: %d\n", err);
            return err;
        }
    
        err = adc_read(adc_channels[1].dev, &sequence2);
        if (err < 0)
        {
            printk("ADC read error on channel 1: %d\n", err);
            return err;
        }
    
        printk("Raw ADC: Channel 0 = %" PRId16 ", Channel 1 = %" PRId16 "\n", buf0, buf2);
    
        // Convert raw ADC to millivolts
        int32_t val_mv0 = buf0;
        int32_t val_mv1 = buf2;
    
        adc_raw_to_millivolts_dt(&adc_channels[0], &val_mv0);
        adc_raw_to_millivolts_dt(&adc_channels[1], &val_mv1);
    
        // Treat negative values as zero
        photodiode_one_mv = (val_mv0 < 0) ? 0 : val_mv0;
        photodiode_two_mv = (val_mv1 < 0) ? 0 : val_mv1;
    
        sum_photodiode_one += photodiode_one_mv;
        sum_photodiode_two += photodiode_two_mv;
    
        printk("Converted: photodiode_one_mv = %d mV, photodiode_two_mv = %d mV\n", photodiode_one_mv, photodiode_two_mv);
        printk("sum_photodiode_one: %d\n", sum_photodiode_one);
        printk("sum_photodiode_two: %d\n", sum_photodiode_two);
    
        return photodiode_two_mv;
    }
    
    void calculateBilirubin()
    {
        // Check for division by zero
        if (sample_count == 0)
        {
            printk("Error: No samples collected!\n");
            return;
        }
    
        avg_photodiode_one = sum_photodiode_one / sample_count;
        avg_photodiode_two = sum_photodiode_two / sample_count;
    
        printk("avg_photodiode_one: %d\n", avg_photodiode_one);
        printk("avg_photodiode_two: %d\n", avg_photodiode_two);
        printk("sample_count: %d\n", sample_count);
    
        int int_part_1 = avg_photodiode_one / 1000;
        int frac_part_1 = avg_photodiode_one % 1000;
    
        printk("PD1 = %d.%03d V\n", int_part_1, frac_part_1);
        snprintf(PD1_str, sizeof(PD1_str), "%d.%03d V", int_part_1, frac_part_1);
    
        int int_part_2 = avg_photodiode_two / 1000;
        int frac_part_2 = avg_photodiode_two % 1000;
    
        printk("PD2 = %d.%03d V\n", int_part_2, frac_part_2);
        snprintf(PD2_str, sizeof(PD2_str), "%d.%03d V", int_part_2, frac_part_2);
    
        if (avg_photodiode_one <= 0)
        {
            bilirubinValue = 0xFFFF;
            snprintf(bilirubinValue_str, sizeof(bilirubinValue_str), "E01");
    
            printk("bilirubinValue: E01 (PD1 is zero or negative)\n");
            updateGUI();
            return;
        }
    
        float pd_ratio = (float)avg_photodiode_two / (float)avg_photodiode_one;
        printk("pd_ratio: %.3f\n", (double)pd_ratio);
        snprintf(pd_ratio_str, sizeof(pd_ratio_str), "%.3f", (double)pd_ratio);
        updateGUI();
    
        if (pd_ratio <= 0.0f)
        {
            pd_ratio = 0.001f;
            // snprintf(pd_ratio_str, sizeof(pd_ratio_str), "0.001");
        }
    
        float log_pd = log10f(pd_ratio);
        float bilirubin_temp = 2.005f * log_pd * log_pd + 13.417f * log_pd - 2.4092f;
    
        printk("log_pd: %.6f\n", log_pd);
        printk("bilirubin_temp: %.3f\n", bilirubin_temp);
    
        if (bilirubin_temp < 0.00f || bilirubin_temp > 25.00f)
        {
            bilirubinValue = 0xFFFF;
            snprintf(bilirubinValue_str, sizeof(bilirubinValue_str), "E01");
            printk("bilirubinValue: E01 (out of range: %.3f)\n", bilirubin_temp);
            updateGUI();
            return;
        }
    
        bilirubinValue = (uint16_t)(bilirubin_temp * 100); // Example: 11.16 → 1116
    
        int int_part = bilirubinValue / 100;
        int frac_part = bilirubinValue % 100;
    
        printk("bilirubinValue: %d.%02d\n", int_part, frac_part);
        snprintf(bilirubinValue_str, sizeof(bilirubinValue_str), "%d.%02d", int_part, frac_part);
    
        // Update GUI with all new values
        updateGUI();
    }
    
    void resetAll()
    {
        k_timer_stop(&adc_timer);
        adc_timeout = false;
        k_timer_stop(&adc_timer);
        k_timer_stop(&display_timer);
        display_timeout = false;
        conversion_complete = false;
        sample_count = 0;
    
        bilirubinValue = 0;
        photodiode_one_mv = 0;
        photodiode_two_mv = 0;
        sum_photodiode_one = 0;
        sum_photodiode_two = 0;
        avg_photodiode_one = 0;
        avg_photodiode_two = 0;
    }
    
    void adc_suspend_all(void)
    {
        for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
            int err = pm_device_action_run(adc_channels[i].dev,
                                           PM_DEVICE_ACTION_SUSPEND);
            if (err < 0) {
                printk("Unable to suspend ADC device %s (err %d)\n",
                       adc_channels[i].dev->name, err);
            } else {
                printk("ADC device %s suspended\n", adc_channels[i].dev->name);
            }
        }
    }
    
    
    
    void EnterPowerdown(void)
    {
        printk("=== ENTERING POWERDOWN SEQUENCE ===\n");
    
        // Turn off all LEDs
        printk("Turning off LEDs...\n");
        int ret = gpio_pin_set_dt(&led0, 0);
        printk("LED0 off: %s\n", ret == 0 ? "OK" : "FAILED");
    
        ret = gpio_pin_set_dt(&led1, 0);
        printk("LED1 off: %s\n", ret == 0 ? "OK" : "FAILED");
    
        ret = gpio_pin_set_dt(&led, 0);
        printk("Backlight off: %s\n", ret == 0 ? "OK" : "FAILED");
    
        ret = gpio_pin_set_dt(&led2, 0);
        printk("LED2 off: %s\n", ret == 0 ? "OK" : "FAILED");
    
        // Stop and suspend PWM
        printk("Stopping PWM...\n");
        pwm_set_dt(&pwm_led0, 0, 0);
        ret = pm_device_action_run(pwm_led0.dev, PM_DEVICE_ACTION_SUSPEND);
        printk("PWM suspend: %s (ret=%d)\n", ret == 0 ? "OK" : "FAILED", ret);
    
        // Put QSPI Flash into deep power-down
        printk("Putting flash into deep power-down...\n");
        // flash_power_down();
    
        // Stop all timers
        printk("Stopping all timers...\n");
        k_timer_stop(&adc_timer);
        k_timer_stop(&led_timer);
        k_timer_stop(&pwm_timer);
        k_timer_stop(&display_timer);
        printk("Timers stopped\n");
    
         adc_suspend_all();
    
        // Add a small delay to ensure all operations complete
        printk("Final delay before powerdown...\n");
        k_sleep(K_MSEC(100));
    
        printk("=== CALLING sys_poweroff() NOW ===\n");
        printk("If you see this message again after reset, powerdown worked!\n");
    
        // Force flush any remaining log messages
        k_sleep(K_MSEC(10));
    
        sys_poweroff();
    
        // This should NEVER be reached if powerdown works
        printk("ERROR: sys_poweroff() returned! Powerdown failed!\n");
        printk("Entering infinite loop instead...\n");
        while (1) {
            k_sleep(K_SECONDS(1));
            printk("Still running... powerdown didn't work\n");
        }
    }
    
    
    int main(void)
    {
        printk("\n=== SYSTEM STARTUP ===\n");
        printk("Boot time: %llu ms\n", k_uptime_get());
    
        k_sleep(K_MSEC(100));  // Let debugger / clocks stabilize
    
        
    
        printk("QSPI JEDEC ID Read & Flash Byte Test\n");
    
        const struct device *flash_dev = DEVICE_DT_GET(FLASH_NODE);
        if (!device_is_ready(flash_dev)) {
            printk("Flash device not ready!\n");
        } else {
            printk("Flash device ready\n");
        }
    
        // Try to read JEDEC ID via custom instruction
        // read_qspi_jedec_id();
    
        printk("Proceeding to powerdown test...\n");
        k_sleep(K_MSEC(500));
    
        EnterPowerdown();
       
        // uart_suspend();
    
        while (1) {
            k_sleep(K_FOREVER);
        }
    }
    
    where  i got in terminal as 
     *** Using Zephyr OS v3.6.99-100befc70c74 ***
    00> 
    00> === SYSTEM STARTUP ===
    00> Boot time: 154 ms
    00> QSPI JEDEC ID Read & Flash Byte Test
    00> Flash device ready
    00> Proceeding to powerdown test...
    00> === ENTERING POWERDOWN SEQUENCE ===
    00> Turning off LEDs...
    00> LED0 off: OK
    00> LED1 off: OK
    00> Backlight off: OK
    00> LED2 off: OK
    00> Stopping PWM...
    00> [00:00:00.756,042] <dbg> pwm_nrf_sw: pwm_nrf_sw_set_cycles: channel 0, period 0, pulse 0
    00> PWM suspend: FAILED (ret=-88)
    00> Putting flash into deep power-down...
    00> Stopping all timers...
    00> Timers stopped
    00> Unable to suspend ADC device adc@40007000 (err -88)
    00> Unable to suspend ADC device adc@40007000 (err -88)
    00> Unable to suspend ADC device adc@40007000 (err -88)
    00> Final delay before powerdown...
    00> === CALLING sys_poweroff() NOW ===
    00> If you see this message again after reset, powerdown worked!
    pls help me to power down PWM,ADC and FLASH where flash used windbond

Reply
  • here i will upload my main.c where i tried to sleep mode for adc and pwm with terminal output 

    /*
     * Copyright (c) 2018 Jan Van Winkel <[email protected]>
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <inttypes.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/drivers/display.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/drivers/flash.h>
    #include <lvgl.h>
    #include <stdio.h>
    #include <string.h>
    #include <nrfx_qspi.h>
    #include <hal/nrf_qspi.h>
    #include <zephyr/kernel.h>
    #include <lvgl_input_device.h>
    #include <stdio.h>
    #include <zephyr/drivers/pwm.h>
    #include <zephyr/pm/device.h>
    
    // #include "Vtlogo565.h"
    // #include"Billirubino.h"
    // #include "Billirubin.h"
    #include <zephyr/drivers/adc.h>
    #include <zephyr/sys/util.h>
    #include <stdlib.h>
    #include <math.h>
    #include <zephyr/sys/poweroff.h>
    #include <zephyr/sys/reboot.h>
    
    #include "ui.h"
    #include "vars.h"
    #include "actions.h"
    #include "structs.h"
    #include "screens.h"
    
    using namespace eez;
    using namespace eez::flow;
    
    #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(app);
    static uint8_t sleepCount = 0;
    #define LED1_NODE DT_NODELABEL(led1)
    #define LED0_NODE DT_NODELABEL(led0)
    #define LED2_NODE DT_NODELABEL(led2)
    int16_t buf0, buf2, buf3;
    char *variable;
    lv_obj_t *main_screen;
    lv_obj_t *count_Value;
    uint16_t bilirubinValue = 0;
    char bilirubinValue_str[16];
    char PD1_str[16];
    char PD2_str[16];
    char pd_ratio_str[16];
    char battery_str[5];
    static bool offFlag = false;
    volatile bool adc_timeout = false;
    bool conversion_complete = false;
    bool display_timeout = false;
    
    #define PWM_FREQUENCY_HZ 4000U                          // Set frequency to 4 kHz
    #define PWM_PERIOD_NS (NSEC_PER_SEC / PWM_FREQUENCY_HZ) // 250,000 ns (250 µs)
    #define DUTY_CYCLE_PERCENT 70                           // Set duty cycle to 50%
    uint32_t pulse_width_ns = (PWM_PERIOD_NS * DUTY_CYCLE_PERCENT) / 100;
    
    #define FLASH_NODE DT_NODELABEL(w25q64)
    const struct device *flash_dev = DEVICE_DT_GET(FLASH_NODE);
    
    int32_t photodiode_one_mv = 0;
    int32_t photodiode_two_mv = 0;
    int32_t sum_photodiode_one = 0;
    int32_t sum_photodiode_two = 0;
    int32_t avg_photodiode_one = 0;
    int32_t avg_photodiode_two = 0;
    
    float phd1 = 0.0f;
    float phd2 = 0.0f;
    float value = 0.0f;
    // int32_t pd1_mv;
    int32_t pd2_mv;
    int32_t avg_pd1 = 0;
    int32_t avg_pd2 = 0;
    int battery_level = 0;
    float ratio = 0.0f;
    // char adc_ratio_str[32] = {0};
    static uint32_t battery_counter = 0;
    
    // #define CMD_READ_JEDEC_ID 0x9F
    #define CMD_POWER_DOWN    0xB9
    
    #if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
        !DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
    #error "No suitable devicetree overlay specified"
    #endif
    
    #define DT_SPEC_AND_COMMA(node_id, prop, idx) \
        ADC_DT_SPEC_GET_BY_IDX(node_id, idx),
    
    /* ADC channel configurations */
    static const struct adc_dt_spec adc_channels[] = {
        DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels, DT_SPEC_AND_COMMA)};
    
    struct adc_sequence sequence0 = {
        .buffer = &buf0,
        .buffer_size = sizeof(buf0),
    };
    
    struct adc_sequence sequence2 = {
        .buffer = &buf2,
        .buffer_size = sizeof(buf2),
    };
    
    struct adc_sequence sequence3 = {
        .buffer = &buf3,
        .buffer_size = sizeof(buf3),
    };
    bool stopFlag = false;
    int32_t volt = 0;
    volatile bool led2_on = false; // Flag to track if LED2 is on
    void EnterPowerdown();
    #ifdef CONFIG_GPIO
    static struct gpio_dt_spec button_gpio = GPIO_DT_SPEC_GET_OR(
        DT_ALIAS(sw1), gpios, {0}); // Button 1
    
    static struct gpio_callback button_callback;
    static struct gpio_dt_spec button_onoff = GPIO_DT_SPEC_GET_OR(DT_ALIAS(sw0), gpios, {0}); // Button 0 (e.g., ON/OFF)
    static struct gpio_callback button_onoff_callback;
    
    #endif
    
    static uint64_t last_activity_time = 0;
    static const uint32_t IDLE_TIMEOUT_MS = 40000; // 32 seconds
    
    #define LED_ON_DURATION_MS 200
    void led_timer_handler(struct k_timer *timer_id); // forward declaration
    K_TIMER_DEFINE(led_timer, led_timer_handler, NULL);
    
    #define ADC_DURATION_MS 10
    void adc_timer_handler(struct k_timer *timer_id); // forward declaration
    K_TIMER_DEFINE(adc_timer, adc_timer_handler, NULL);
    
    #define PWM_ON_DURATION_MS 200
    void pwm_timer_handler(struct k_timer *timer_id); // forward declaration
    K_TIMER_DEFINE(pwm_timer, pwm_timer_handler, NULL);
    
    #define DISPLAY_DURATION_MS 20000
    void display_timer_handler(struct k_timer *timer_id); // forward declaration
    K_TIMER_DEFINE(display_timer, display_timer_handler, NULL);
    
    uint64_t led2_on_timestamp = 0;
    uint64_t led2_off_timestamp = 0;
    // int32_t pd1_sum = 0, pd2_sum = 0;
    uint32_t sample_count = 0;
    
    static uint32_t count = 0;
    static uint32_t countbutton = 0;
    
    static bool led2_ever_used = false;
    static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_NODELABEL(ledbacklight), gpios);
    static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
    static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    static const struct gpio_dt_spec led2 = GPIO_DT_SPEC_GET(LED2_NODE, gpios);
    static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0));
    
    void updateGUI()
    {
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_BILIRUBIN_VALUE_STR, bilirubinValue_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_BILIRUBIN_LABEL, bilirubinValue_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_PD1, PD1_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_PD2, PD2_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_RATIO, pd_ratio_str);
        setGlobalVariable(FLOW_GLOBAL_VARIABLE_BATTERY_PERCENTAGE, battery_str);
    }
    
    void flash_power_down(void)
    {
        nrf_qspi_cinstr_conf_t cinstr_cfg = {
            .opcode    = CMD_POWER_DOWN,
            .length    = NRF_QSPI_CINSTR_LEN_1B, // Only 1 byte command
            .io2_level = true,
            .io3_level = true,
            .wipwait   = false,
            .wren      = false
        };
    
        nrfx_err_t err = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        if (err != NRFX_SUCCESS) {
            printk("Failed to send POWER-DOWN (B9h): %d\n", err);
        } else {
            printk("Flash entered deep power-down mode.\n");
        }
    }
    static void button_isr_callback(const struct device *port,
                                    struct gpio_callback *cb,
                                    uint32_t pins)
    {
        last_activity_time = k_uptime_get();
        int button_state = gpio_pin_get_dt(&button_gpio);
    
        if (button_state == 1)
        { // Button pressed
            gpio_pin_set_dt(&led2, 1);
            led2_on = true;
            // pd1_sum = 0;
            // pd2_sum = 0;
            k_timer_stop(&display_timer);
            display_timeout = false;
            sum_photodiode_one = 0;
            sum_photodiode_two = 0;
            sample_count = 0;
            led2_on_timestamp = k_uptime_get();
            k_timer_start(&led_timer, K_MSEC(LED_ON_DURATION_MS), K_NO_WAIT);
            k_timer_start(&adc_timer, K_MSEC(ADC_DURATION_MS), K_NO_WAIT);
            k_timer_start(&pwm_timer, K_MSEC(PWM_ON_DURATION_MS), K_NO_WAIT);
            printk("LED2 turned ON at %llu ms\n", led2_on_timestamp);
    
            int ret = pwm_set_dt(&pwm_led0, PWM_PERIOD_NS, pulse_width_ns);
            if (ret < 0)
            {
                printk("Failed to start PWM: %d\n", ret);
            }
            else
            {
                printk("PWM started with duty cycle %d ns\n", pulse_width_ns);
            }
    
            printk("LED2 turned ON at %llu ms\n", led2_on_timestamp);
        }
    
        else if (button_state == 0)
        { // Button released
            printk("Button released - stopping sampling\n");
            pwm_set_dt(&pwm_led0, 0, 0);
        }
    }
    
    static void button_onoff_handler(const struct device *dev,
                                     struct gpio_callback *cb,
                                     uint32_t pins)
    {
        // LOG_INF("Wake-up button pressed");
        // last_activity_time = k_uptime_get();
        // EnterPowerdown();
        offFlag = true;
        sleepCount = 0;
        countbutton = 0;
    }
    
    #ifdef CONFIG_LV_Z_ENCODER_INPUT
    static const struct device *lvgl_encoder =
        DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_encoder_input));
    #endif /* CONFIG_LV_Z_ENCODER_INPUT */
    
    #ifdef CONFIG_LV_Z_KEYPAD_INPUT
    static const struct device *lvgl_keypad =
        DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_keypad_input));
    #endif /* CONFIG_LV_Z_KEYPAD_INPUT */
    
    static void lv_btn_click_callback(lv_event_t *e)
    {
        ARG_UNUSED(e);
    
        count = 0;
    }
    
    void adc_timer_handler(struct k_timer *timer_id)
    {
        adc_timeout = true;
    }
    
    void display_timer_handler(struct k_timer *timer_id)
    {
        display_timeout = true;
    }
    
    void led_timer_handler(struct k_timer *timer_id)
    {
        conversion_complete = true;
    }
    
    void pwm_timer_handler(struct k_timer *timer_id)
    {
        int ret = pwm_set_dt(&pwm_led0, 0, 0); // Stop PWM
        if (ret < 0)
        {
            printk("Failed to stop PWM in timer: %d\n", ret);
        }
        else
        {
            printk("PWM stopped by timer\n");
        }
    }
    
    void PWMInit()
    {
        printk("pwminit");
        if (!pwm_is_ready_dt(&pwm_led0))
        {
            printk("Error: PWM device %s is not ready\n", pwm_led0.dev->name);
        }
    }
    
    void AdcInit()
    {
        printk("adcinit");
        for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++)
        {
            if (!device_is_ready(adc_channels[i].dev))
            {
                printk("ADC controller device not ready\n");
            }
    
            int err = adc_channel_setup_dt(&adc_channels[i]);
            if (err < 0)
            {
                printk("Could not setup channel #%d (%d)\n", i, err);
            }
        }
    }
    int calculate_battery_percentage(int32_t val_mv)
    {
        const int32_t FULL_CHARGE_MV = 2965; // Adjust based on your battery specs
        const int32_t EMPTY_CHARGE_MV = 1976;
    
        if (val_mv >= FULL_CHARGE_MV)
            return 100;
        if (val_mv <= EMPTY_CHARGE_MV)
            return 0;
    
        return (int)((val_mv - EMPTY_CHARGE_MV) * 100 / (FULL_CHARGE_MV - EMPTY_CHARGE_MV));
    }
    
    int32_t battery_adc()
    {
        int err;
    
        // Initialize ADC sequence for battery channel (channel 2)
        err = adc_sequence_init_dt(&adc_channels[2], &sequence3);
        if (err < 0)
        {
            printk("Failed to initialize ADC channel 2 sequence\n");
            return err;
        }
    
        err = adc_read(adc_channels[2].dev, &sequence3);
        if (err < 0)
        {
            printk("ADC read error on channel 2: %d\n", err);
            return err;
        }
    
        int32_t val_mv = buf3;
    
        err = adc_raw_to_millivolts_dt(&adc_channels[2], &val_mv);
        if (err < 0)
        {
            printk("Conversion error for channel 2\n");
            return err;
        }
    
        battery_level = calculate_battery_percentage(val_mv);
    
        printk("Battery: %" PRId32 " mV (%d%%)\n", val_mv, battery_level);
        snprintf(battery_str, sizeof(battery_str), "%d", battery_level);
        updateGUI();
    
        return val_mv; // If you want to return mV for display
    }
    
    int32_t adcRead()
    {
        int err;
    
        // Initialize ADC sequences for PD1 (channel 0) and PD2 (channel 1)
        err = adc_sequence_init_dt(&adc_channels[0], &sequence0);
        if (err < 0)
        {
            printk("Failed to initialize ADC channel 0 sequence\n");
            return err;
        }
    
        err = adc_sequence_init_dt(&adc_channels[1], &sequence2);
        if (err < 0)
        {
            printk("Failed to initialize ADC channel 1 sequence\n");
            return err;
        }
    
        // Read ADC values
        err = adc_read(adc_channels[0].dev, &sequence0);
        if (err < 0)
        {
            printk("ADC read error on channel 0: %d\n", err);
            return err;
        }
    
        err = adc_read(adc_channels[1].dev, &sequence2);
        if (err < 0)
        {
            printk("ADC read error on channel 1: %d\n", err);
            return err;
        }
    
        printk("Raw ADC: Channel 0 = %" PRId16 ", Channel 1 = %" PRId16 "\n", buf0, buf2);
    
        // Convert raw ADC to millivolts
        int32_t val_mv0 = buf0;
        int32_t val_mv1 = buf2;
    
        adc_raw_to_millivolts_dt(&adc_channels[0], &val_mv0);
        adc_raw_to_millivolts_dt(&adc_channels[1], &val_mv1);
    
        // Treat negative values as zero
        photodiode_one_mv = (val_mv0 < 0) ? 0 : val_mv0;
        photodiode_two_mv = (val_mv1 < 0) ? 0 : val_mv1;
    
        sum_photodiode_one += photodiode_one_mv;
        sum_photodiode_two += photodiode_two_mv;
    
        printk("Converted: photodiode_one_mv = %d mV, photodiode_two_mv = %d mV\n", photodiode_one_mv, photodiode_two_mv);
        printk("sum_photodiode_one: %d\n", sum_photodiode_one);
        printk("sum_photodiode_two: %d\n", sum_photodiode_two);
    
        return photodiode_two_mv;
    }
    
    void calculateBilirubin()
    {
        // Check for division by zero
        if (sample_count == 0)
        {
            printk("Error: No samples collected!\n");
            return;
        }
    
        avg_photodiode_one = sum_photodiode_one / sample_count;
        avg_photodiode_two = sum_photodiode_two / sample_count;
    
        printk("avg_photodiode_one: %d\n", avg_photodiode_one);
        printk("avg_photodiode_two: %d\n", avg_photodiode_two);
        printk("sample_count: %d\n", sample_count);
    
        int int_part_1 = avg_photodiode_one / 1000;
        int frac_part_1 = avg_photodiode_one % 1000;
    
        printk("PD1 = %d.%03d V\n", int_part_1, frac_part_1);
        snprintf(PD1_str, sizeof(PD1_str), "%d.%03d V", int_part_1, frac_part_1);
    
        int int_part_2 = avg_photodiode_two / 1000;
        int frac_part_2 = avg_photodiode_two % 1000;
    
        printk("PD2 = %d.%03d V\n", int_part_2, frac_part_2);
        snprintf(PD2_str, sizeof(PD2_str), "%d.%03d V", int_part_2, frac_part_2);
    
        if (avg_photodiode_one <= 0)
        {
            bilirubinValue = 0xFFFF;
            snprintf(bilirubinValue_str, sizeof(bilirubinValue_str), "E01");
    
            printk("bilirubinValue: E01 (PD1 is zero or negative)\n");
            updateGUI();
            return;
        }
    
        float pd_ratio = (float)avg_photodiode_two / (float)avg_photodiode_one;
        printk("pd_ratio: %.3f\n", (double)pd_ratio);
        snprintf(pd_ratio_str, sizeof(pd_ratio_str), "%.3f", (double)pd_ratio);
        updateGUI();
    
        if (pd_ratio <= 0.0f)
        {
            pd_ratio = 0.001f;
            // snprintf(pd_ratio_str, sizeof(pd_ratio_str), "0.001");
        }
    
        float log_pd = log10f(pd_ratio);
        float bilirubin_temp = 2.005f * log_pd * log_pd + 13.417f * log_pd - 2.4092f;
    
        printk("log_pd: %.6f\n", log_pd);
        printk("bilirubin_temp: %.3f\n", bilirubin_temp);
    
        if (bilirubin_temp < 0.00f || bilirubin_temp > 25.00f)
        {
            bilirubinValue = 0xFFFF;
            snprintf(bilirubinValue_str, sizeof(bilirubinValue_str), "E01");
            printk("bilirubinValue: E01 (out of range: %.3f)\n", bilirubin_temp);
            updateGUI();
            return;
        }
    
        bilirubinValue = (uint16_t)(bilirubin_temp * 100); // Example: 11.16 → 1116
    
        int int_part = bilirubinValue / 100;
        int frac_part = bilirubinValue % 100;
    
        printk("bilirubinValue: %d.%02d\n", int_part, frac_part);
        snprintf(bilirubinValue_str, sizeof(bilirubinValue_str), "%d.%02d", int_part, frac_part);
    
        // Update GUI with all new values
        updateGUI();
    }
    
    void resetAll()
    {
        k_timer_stop(&adc_timer);
        adc_timeout = false;
        k_timer_stop(&adc_timer);
        k_timer_stop(&display_timer);
        display_timeout = false;
        conversion_complete = false;
        sample_count = 0;
    
        bilirubinValue = 0;
        photodiode_one_mv = 0;
        photodiode_two_mv = 0;
        sum_photodiode_one = 0;
        sum_photodiode_two = 0;
        avg_photodiode_one = 0;
        avg_photodiode_two = 0;
    }
    
    void adc_suspend_all(void)
    {
        for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
            int err = pm_device_action_run(adc_channels[i].dev,
                                           PM_DEVICE_ACTION_SUSPEND);
            if (err < 0) {
                printk("Unable to suspend ADC device %s (err %d)\n",
                       adc_channels[i].dev->name, err);
            } else {
                printk("ADC device %s suspended\n", adc_channels[i].dev->name);
            }
        }
    }
    
    
    
    void EnterPowerdown(void)
    {
        printk("=== ENTERING POWERDOWN SEQUENCE ===\n");
    
        // Turn off all LEDs
        printk("Turning off LEDs...\n");
        int ret = gpio_pin_set_dt(&led0, 0);
        printk("LED0 off: %s\n", ret == 0 ? "OK" : "FAILED");
    
        ret = gpio_pin_set_dt(&led1, 0);
        printk("LED1 off: %s\n", ret == 0 ? "OK" : "FAILED");
    
        ret = gpio_pin_set_dt(&led, 0);
        printk("Backlight off: %s\n", ret == 0 ? "OK" : "FAILED");
    
        ret = gpio_pin_set_dt(&led2, 0);
        printk("LED2 off: %s\n", ret == 0 ? "OK" : "FAILED");
    
        // Stop and suspend PWM
        printk("Stopping PWM...\n");
        pwm_set_dt(&pwm_led0, 0, 0);
        ret = pm_device_action_run(pwm_led0.dev, PM_DEVICE_ACTION_SUSPEND);
        printk("PWM suspend: %s (ret=%d)\n", ret == 0 ? "OK" : "FAILED", ret);
    
        // Put QSPI Flash into deep power-down
        printk("Putting flash into deep power-down...\n");
        // flash_power_down();
    
        // Stop all timers
        printk("Stopping all timers...\n");
        k_timer_stop(&adc_timer);
        k_timer_stop(&led_timer);
        k_timer_stop(&pwm_timer);
        k_timer_stop(&display_timer);
        printk("Timers stopped\n");
    
         adc_suspend_all();
    
        // Add a small delay to ensure all operations complete
        printk("Final delay before powerdown...\n");
        k_sleep(K_MSEC(100));
    
        printk("=== CALLING sys_poweroff() NOW ===\n");
        printk("If you see this message again after reset, powerdown worked!\n");
    
        // Force flush any remaining log messages
        k_sleep(K_MSEC(10));
    
        sys_poweroff();
    
        // This should NEVER be reached if powerdown works
        printk("ERROR: sys_poweroff() returned! Powerdown failed!\n");
        printk("Entering infinite loop instead...\n");
        while (1) {
            k_sleep(K_SECONDS(1));
            printk("Still running... powerdown didn't work\n");
        }
    }
    
    
    int main(void)
    {
        printk("\n=== SYSTEM STARTUP ===\n");
        printk("Boot time: %llu ms\n", k_uptime_get());
    
        k_sleep(K_MSEC(100));  // Let debugger / clocks stabilize
    
        
    
        printk("QSPI JEDEC ID Read & Flash Byte Test\n");
    
        const struct device *flash_dev = DEVICE_DT_GET(FLASH_NODE);
        if (!device_is_ready(flash_dev)) {
            printk("Flash device not ready!\n");
        } else {
            printk("Flash device ready\n");
        }
    
        // Try to read JEDEC ID via custom instruction
        // read_qspi_jedec_id();
    
        printk("Proceeding to powerdown test...\n");
        k_sleep(K_MSEC(500));
    
        EnterPowerdown();
       
        // uart_suspend();
    
        while (1) {
            k_sleep(K_FOREVER);
        }
    }
    
    where  i got in terminal as 
     *** Using Zephyr OS v3.6.99-100befc70c74 ***
    00> 
    00> === SYSTEM STARTUP ===
    00> Boot time: 154 ms
    00> QSPI JEDEC ID Read & Flash Byte Test
    00> Flash device ready
    00> Proceeding to powerdown test...
    00> === ENTERING POWERDOWN SEQUENCE ===
    00> Turning off LEDs...
    00> LED0 off: OK
    00> LED1 off: OK
    00> Backlight off: OK
    00> LED2 off: OK
    00> Stopping PWM...
    00> [00:00:00.756,042] <dbg> pwm_nrf_sw: pwm_nrf_sw_set_cycles: channel 0, period 0, pulse 0
    00> PWM suspend: FAILED (ret=-88)
    00> Putting flash into deep power-down...
    00> Stopping all timers...
    00> Timers stopped
    00> Unable to suspend ADC device adc@40007000 (err -88)
    00> Unable to suspend ADC device adc@40007000 (err -88)
    00> Unable to suspend ADC device adc@40007000 (err -88)
    00> Final delay before powerdown...
    00> === CALLING sys_poweroff() NOW ===
    00> If you see this message again after reset, powerdown worked!
    pls help me to power down PWM,ADC and FLASH where flash used windbond

Children
Related