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

PWM Driver

Hello,

I want to use the PWM driver to change the output voltage with respect to analog input voltage. If I call the simple_playback_sequence from the SAADC event handler, the voltage only raises for that time but if I call the same function from the while(); loop in main, it remains constant. I am giving LOOPS, no repeats and no end delay. Is there any specific reason that I can't call PWM from the event handlers and have to do it only from the infinite while loop?

Parents Reply Children
  • Sorry for the late reply, consider timer_handler as a function I call using app_timer library and pwm_change as a function I want to change the PWM value. count is a global variable

    Code that Works :

    void timer_handler()

    {

    count+= 1;

    }

    void pwm_change()

    {

    nrf_pwm_values_common_t seq_values[] = {count};
    nrf_pwm_sequence_t const seq =
    {
    .values.p_common = seq_values,
    .length = NRF_PWM_VALUES_LENGTH(seq_values),
    .repeats = 0,
    .end_delay = 0
    };

    nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);

    }

    int main()

    {

    // Initialise peripherals...

    while(1)

    {

    idle_state_handle();

    pwm_change();

    }

    }

    Code that does not Work :

    void timer_handler()

    {

    count+= 1;

    pwm_change();

    }

    void pwm_change()

    {

    nrf_pwm_values_common_t seq_values[] = {count};
    nrf_pwm_sequence_t const seq =
    {
    .values.p_common = seq_values,
    .length = NRF_PWM_VALUES_LENGTH(seq_values),
    .repeats = 0,
    .end_delay = 0
    };

    nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);

    }

    int main()

    {

    // Initialise peripherals...

    while(1)

    {

    idle_state_handle();     

     }

    }

    The place where I call pwm_change is what's changed between the codes. If i call from main(), it functions well but if I call from any event handler, the PWM breaks continuously.

  • Hi,

    I do not see any specific issue with setting the PWM from an event handler, but that probably just happens to trigger another issue in your code. I notice that you have the PWM values on the stack, and that will typically cause them to get corrupted as the memory needs to be valid for as long as they are used. You should make them static instead. (API doc states this: "The array containing the duty cycle values for the specified sequence must be in RAM and cannot be allocated on the stack."

  • Hello, Sorry for this extremely late reply.

    I did make the variable count as static in the second code and it still does not work.

    You should make them static instead.

    Could you please explain what you meant by this?

  • Your variables are located on the stack, and that is explicitly not supported. Make them static (write static before the type when you declare them) to ensure that they are not on the stack and remains valid after the function returns.

  • Still not working.

    Updated code.

    static uint16_t count = 0;

    void timer_handler()

    {

    count+= 1;

    pwm_change();

    }

    void pwm_change()
    {
    nrf_pwm_values_common_t seq_values[] = {count};
    nrf_pwm_sequence_t const seq =
    {
    .values.p_common = seq_values,
    .length = NRF_PWM_VALUES_LENGTH(seq_values),
    .repeats = 0,
    .end_delay = 0
    };
    nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);
    }

Related