This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

High current problem for app_pwm SDK13.0

Hi,

I am working on nRF52832 with SDK13.0 + GCC Eclipse.

I have used 2 app_pwm instances for driving a 3 color led. Once I init the pwm and set the duty cycle, the current increase from 3uA (sleep state) to 6.5mA. This 6.5mA current is just for the MCU as I have a separate power supply for the LED, the MCU is sinking current from the LED. When I call app_pwm_disable and app_pwm_uninit, the current still keep at 6.5mA.

Further more, if I just init the pwm but not set the duty cycle, it would be just 1mA and able to go back to 3uA sleep when I disable the pwm.

I have searched for some post about the pwm which mention about the pan73_workaround fix but I already found that in app_pwm_disable.

I have 2 questions: Is 6.5mA normal for using app_pwm? How to remove that 6.5mA when I disable the pwm?

Regards, George

  • Hi,

    Q: Is 6.5mA normal for using app_pwm?

    A: No, this is not normal and indicates that the CPU is not entering System ON sleep mode, and is instead in RUN mode.

    How are you entering sleep mode ?

  • Let me describe more details about the system.

    I have a MCU connected to a motion sensor through SPI, FreeRTOS is used as the OS. TICKLESS_IDLE is used for the sleep.

    Normally the device keep at sleep and consume ~3uA at sleep state. When a motion detected by the sensor, a interrupt will be generated to wake up the MCU.

    Currently when the MCU woke up, I will init a app_pwm drive instance and turn on the LED. There is a LED task which will update the duty cycle for each 10ms to show some animation.

    If no more interrupt event detected in 2s, the LED will turn off and every tasks are keeping at block. Everything are fine if I am not setting the PWM dute cycle as I mention above.

    But once I updated the dute cycle, I discover a 6.5mA current for the MCU and this current is keep consuming even the LED is off and the app_pwm_disable and app_pwm_uninit are called.

  • Attached some part of the code for your reference:

    void pwm_open(void) {
    ret_code_t UNUSED err_code;
    
    /* 2-channel PWM, 200Hz, output on DK LED pins. */
    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(5000L, LED_1, LED_2);
    app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000L, LED_3);
    
    /* Switch the polarity of the second channel. */
    pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
    pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_LOW;
    pwm2_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
    
    /* Initialize and enable PWM. */
    err_code = app_pwm_init(&PWM_1, &pwm1_cfg, NULL);
    PWM_TRACE("PWM 1 init %d\n", err_code);
    err_code = app_pwm_init(&PWM_2, &pwm2_cfg, NULL);
    PWM_TRACE("PWM 2 init %d\n", err_code);
    
    app_pwm_enable(&PWM_1);
    app_pwm_enable(&PWM_2);
    
    pwm_set_all_channels(0, 0, 0);
    

    }

    void pwm_close(void) {
    app_pwm_disable(&PWM_1);
    app_pwm_disable(&PWM_2);
    app_pwm_uninit(&PWM_1);
    app_pwm_uninit(&PWM_2);
    

    }

    void pwm_set(uint8_t channel, uint16_t duty_cycle) {
    float duty_as_frac = duty_cycle / DUTY_MAX;
    
    switch(channel) {
        default:
        case 0:
            duty_cycle = (uint16_t)(RED_SCALE * duty_as_frac * app_pwm_cycle_ticks_get(&PWM_1));
            while(app_pwm_channel_duty_ticks_set(&PWM_1, 0, duty_cycle) == NRF_ERROR_BUSY);
            break;
        case 1:
            duty_cycle = (uint16_t)(GREEN_SCALE * duty_as_frac * app_pwm_cycle_ticks_get(&PWM_1));
            while(app_pwm_channel_duty_ticks_set(&PWM_1, 1, duty_cycle) == NRF_ERROR_BUSY);
            break;
        case 2:
            duty_cycle = (uint16_t)(BLUE_SCALE * duty_as_frac * app_pwm_cycle_ticks_get(&PWM_2));
            while(app_pwm_channel_duty_ticks_set(&PWM_2, 0, duty_cycle) == NRF_ERROR_BUSY);
            break;
    }
    

    }

  • I see that you are using float when setting the duty cycle, so the issue could be casued by this bug. Could you try to use double instead of float, and see if that solves your problem?

  • Hi Sigurd,

    I have try that but seem cannot solve the problem. I have try the same code on the nRF52 DK board and I got the same result so I think it is a MCU peripheral problem and not a hardware problem.

    Today I have done more test on it. The start and stop of the PWM is function correctly, so I think it is not a while loop problem for polling NRF_ERROR_BUSY. One observation which I think is important, once I call the app_pwm_channel_duty_ticks_set, the current rise to 6.5mA, which is higher than normal MCU full running current (~4.5mA). If I am not calling the app_pwm_channel_duty_ticks_set, all the stuff works fine. Is that some hints which can help?

Related