Spikes in current consumption after using semaphores





can anyone tell me what are these spikes

i am some part of my code:

_SPRINTLN(DEBUG_INFO, "LOW-PWR-SYS-ON"); // debug log to show device will enter standby state

        // turn off peripherals
        pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND);
        pm_device_action_run(adc_dev, PM_DEVICE_ACTION_SUSPEND);

        // Block (sleep) the main thread, it will wake up on GPIO interrupt or timer timeout
        k_sem_take(&main_sem, K_FOREVER);

        pm_device_action_run(uart_dev, PM_DEVICE_ACTION_RESUME);
        pm_device_action_run(adc_dev, PM_DEVICE_ACTION_RESUME);

Parents Reply Children
  • I have applied below changes in mode=1 and did not see any raise in current once it enters into SYSTEM_OFF mode.

    void shutdown_cpu(bool mode)
    {
        led_ctrl(HIGH, HIGH, HIGH);
        du_radio_sleep(DU_SLEEP_SHUTDOWN);
        sx126x_hal_deinit();
    
        // clear all the wakeup reasons before going to sleep
        clear_wakeup_reason();
    
        // get zephyr-console pointer:
        const struct device *uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
    
        if (mode)
        {
            _SPRINTLN(DEBUG_INFO, "LOW-PWR-SYS-OFF"); // debug log to show device will enter shutdown state
            gf_pwr_once = 0;
    
            // Disable the UART, SPI, I2C, and other communication peripherals
            NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Disabled;
            NRF_SPI0->ENABLE = SPI_ENABLE_ENABLE_Disabled;
            NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Disabled;
    
            // Disable the ADC (if enabled)
            NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Disabled;
    
            // Disable RTC
            NRF_RTC0->TASKS_STOP = 1;
    
            // Disable timers
            NRF_TIMER0->TASKS_STOP = 1;
    
            // Disable PWM
            NRF_PWM0->ENABLE = PWM_ENABLE_ENABLE_Disabled;
    
            // Disable the radio (Bluetooth)
            NRF_RADIO->POWER = RADIO_POWER_POWER_Disabled;
    
            // Disable the CPU clock and enter low power mode
            NRF_POWER->TASKS_LOWPWR = 1;
    
            // Enter System OFF mode
            NRF_POWER->SYSTEMOFF = 1; // This will cause the chip to enter System OFF mode
        }
        else
        {
            _SPRINTLN(DEBUG_INFO, "LOW-PWR-SYS-ON"); // debug log to show device will enter standby state
    
            // turn off peripherals
            pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND);
            // Disable the UART, SPI, I2C, and other communication peripherals
    
            NRF_SPI0->ENABLE = SPI_ENABLE_ENABLE_Disabled;
            NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Disabled;
    
            // Disable the ADC (if enabled)
            NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Disabled;
    
            // Disable RTC
            NRF_RTC0->TASKS_STOP = 1;
    
            // Disable timers
            NRF_TIMER0->TASKS_STOP = 1;
    
            // Disable PWM
            NRF_PWM0->ENABLE = PWM_ENABLE_ENABLE_Disabled;
    
            // Disable the radio (Bluetooth)
            NRF_RADIO->POWER = RADIO_POWER_POWER_Disabled;
    
            // Disable the CPU clock and enter low power mode
            NRF_POWER->TASKS_LOWPWR = 1;
    
            // If 'use_timer' is true, it means we want to use the timer to wake up the device after 'RTC_TIME' seconds.
            // This will block the main thread until the timer expires or an interrupt occurs (based on the RTC_TIME).
            if (use_timer)
            {
    
                // Wait for the semaphore to be given, with a timeout of 'RTC_TIME' seconds.
                // If the semaphore is not given within this period, it means a timeout has occurred.
                int ret = k_sem_take(&main_sem, K_SECONDS(RTC_TIME)); // Store the return value for error handling
    
                // Error handling based on the return value of k_sem_take:
                if (ret == 0)
                {
                    // Semaphore successfully taken, no timeout occurred
                    timeout_flag = false; // Reset the timeout flag
                }
                else if (ret == -EBUSY)
                {
                    // The semaphore was already taken (not a typical case for k_sem_take with timeout)
                    _SPRINTLN(DEBUG_ERROR, "Semaphore already taken. This should not happen.");
    
                    k_msleep(5000);
                    k_sem_take(&main_sem, K_SECONDS(RTC_TIME));
                }
                else if (ret == -EAGAIN)
                {
                    // Timeout occurred
                    timeout_flag = true; // Set the timeout flag to indicate the timer has expired
                    _SPRINTLN(DEBUG_WARNING, "Timer expired without semaphore being taken.");
                }
                else
                {
                    // Catch any other unexpected error codes
                    _SPRINTLN(DEBUG_ERROR, "Unexpected error during semaphore take operation: %d", ret);
                    k_msleep(5000);
                    k_sem_take(&main_sem, K_SECONDS(RTC_TIME));
                }
            }
            else
            {
                // If 'use_timer' is false, block the main thread indefinitely until a GPIO interrupt occurs.
                // The main thread will wake up when a semaphore is given by an ISR.
                int ret = k_sem_take(&main_sem, K_FOREVER); // Store the return value for error handling
    
                // Error handling based on the return value of k_sem_take:
                if (ret != 0)
                {
                    // If we exit unexpectedly (e.g., an ISR failure or other issue), log the error
                    _SPRINTLN(DEBUG_ERROR, "Failed to take semaphore with indefinite wait.");
                    k_msleep(5000);
                    k_sem_take(&main_sem, K_FOREVER);
                }
            }
    
            pm_device_action_run(uart_dev, PM_DEVICE_ACTION_RESUME);
        }
    
        adc_init();
    
        // lines to be executed after wakeup:
        du_radio_init();
        du_radio_sleep(DU_SLEEP_STANDBY);
        _SPRINTLN(DEBUG_CRITICAL, "WAKE-UP");
        k_msleep(100); // Simultaneous Button press
    }

  • CONFIG_PM=y
    This line does not seem to be doing anything.

  • Again original issue which was associated with spikes in current consumption while main thread is sleeping or blocked with use of semaphore is unresolved
    +
    Plus current consumption of overall pcb is ~10 uA, where nrf52811 SoC is consuming around ~7 uA.

    For this refer mode=0.

Related