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

Initial spike with PWM implementation

Hi,

I am using a PWM to control the output of an LED driver and I am implementing a soft_on function when powering ON the driver, so we have a start_PWM function that looks like this:

static void start_PWM(void)
{
// PWM stuff
    app_pwm_config_t m_pwm0_config = APP_PWM_DEFAULT_CONFIG_1CH(1000, LIGHT_FIXTURE);
    m_pwm0_config.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;

    uint32_t status = app_pwm_init(&PWM0, &m_pwm0_config, NULL);
    APP_ERROR_CHECK(status);
    m_pwm0_max = app_pwm_cycle_ticks_get(&PWM0);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "PWM max ticks: %d\n", m_pwm0_max);

    app_pwm_enable(&PWM0);
    nrf_delay_us(850);
//this is the soft on: for(uint16_t i = 0; i < 300; i++) { //(void) app_pwm_channel_duty_ticks_set(&PWM0, 0, i); while (app_pwm_channel_duty_ticks_set(&PWM0, 0, i) == NRF_ERROR_BUSY); nrf_delay_ms(1); __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "Current dimming: %d\n", i); } __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Soft ON\n"); }

Now, the issue is that there is an initial pulse when powering ON and before the soft on happens. we also tried just simply to set to 0 with:

static void start_PWM(void)
{
// PWM stuff
    app_pwm_config_t m_pwm0_config = APP_PWM_DEFAULT_CONFIG_1CH(1000, LIGHT_FIXTURE);
    m_pwm0_config.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;

    uint32_t status = app_pwm_init(&PWM0, &m_pwm0_config, NULL);
    APP_ERROR_CHECK(status);
    m_pwm0_max = app_pwm_cycle_ticks_get(&PWM0);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "PWM max ticks: %d\n", m_pwm0_max);

    app_pwm_enable(&PWM0);
    nrf_delay_us(850);
    (void) app_pwm_channel_duty_ticks_set(&PWM0, 0, 0);

}

But still, there is that initial pulse. We had a similar issue few weeks ago with this thread: https://devzone.nordicsemi.com/f/nordic-q-a/41616/initial-pulse-while-starting-a-pwm-application we thought that we solved but now we have it again...

and just to clarify, if we don't set anything after the enable function then there is no pulse:

static void start_PWM(void)
{
// PWM stuff
    app_pwm_config_t m_pwm0_config = APP_PWM_DEFAULT_CONFIG_1CH(1000, LIGHT_FIXTURE);
    m_pwm0_config.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;

    uint32_t status = app_pwm_init(&PWM0, &m_pwm0_config, NULL);
    APP_ERROR_CHECK(status);
    m_pwm0_max = app_pwm_cycle_ticks_get(&PWM0);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "PWM max ticks: %d\n", m_pwm0_max);

    app_pwm_enable(&PWM0);
}

is there any reason to have that pulse when setting the PWM output?

I am using 15.2.0 SDK and 3.0.0 Mesh SDK.

Parents
  • I see multiple bugs in the PWM libraries, not sure whether that would help. A fix worth trying is to use ms-bit inverted, if you haven't tried already.  The startup pulse is different for Low-High PWM (value) vs. High-Low PWM (0x8000|value). I use differential PWM signals so see both simultaneously; maybe try doing this for your LED drive to see if one signal in your case looks preferable. I also control pin initialisation seperately from the library, but can get a 4uSec unwanted pulse on Low-High but not on High-Low startup.

    So the bugs: From the user manual

    // 6.17.5.15 PSEL.OUT[n] (n=0..3)
    //  Address offset: 0x560 + (n × 0x4)
    //  Output pin select for PWM channel n
    //  Bit number 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    //          ID                                                                         C B A A A A A
    // Reset 0xFFFFFFFF                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    //  ID RW Field Value ID Value Description
    //  A RW PIN [0..31] Pin number
    //  B RW PORT [0..1] Port number
    //  C RW CONNECT Connection   Disconnected 1 Connected 0

    From the library for PWM nrfx_pwm.h and nrfx_pwm.c in SDK 15.2.0:

    /**
     * @brief This value can be added to a pin number to inverse its polarity
     *        (set idle state = 1).
     */
    #define NRFX_PWM_PIN_INVERTED    0x80
    
    static void configure_pins(nrfx_pwm_t const * const p_instance,
                               nrfx_pwm_config_t const * p_config)
    {
        uint32_t out_pins[NRF_PWM_CHANNEL_COUNT];
        uint8_t i;
    
        for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i)
        {
            uint8_t output_pin = p_config->output_pins[i];
            if (output_pin != NRFX_PWM_PIN_NOT_USED)
            {
                bool inverted = output_pin &  NRFX_PWM_PIN_INVERTED;
                out_pins[i]   = output_pin & ~NRFX_PWM_PIN_INVERTED;
    
                if (inverted)
                {
                    nrf_gpio_pin_set(out_pins[i]);
                }
                else
                {
                    nrf_gpio_pin_clear(out_pins[i]);
                }
    
                nrf_gpio_cfg_output(out_pins[i]);
            }
            else
            {
                out_pins[i] = NRF_PWM_PIN_NOT_CONNECTED;
            }
        }
    
        nrf_pwm_pins_set(p_instance->p_registers, out_pins);
    }
    

    There is no inverted bit in the manual; this affects port output initialisation and the use of Port 1.x for PWM.

  • I did try inverting the polarity of the PWM pin which is similar to what you are suggesting.
    That also has a similar spike when powering ON the driver.

  • Have you checked if one of the LED_x definitions in your board file is assigned to the same pin as LIGHT_FIXTURE?

    No, there isn't any definition in the board file that matches with the same pin as LIGHT_FIXTURE.

    Here is what we did, I implemented the start_PWM() function before the initialize() and start(). This doesn't result in any spike. 

    Is there any startup time for the Mesh?

    It looks like this spike is a result of the startup/setup time for Mesh.

  • What pin number do you use for "LIGHT_FIXTURE"? 

  • We are using pin 11 for "LIGHT_FIXTURE".  There is a pin definition as SER_CONN_CHIP_RESET_PIN defined as 11 but that never affected our development till date. We were able to implement PWM and UART communication successfully on pin 11.

  • UART Tx? You should not have both PWM output and UART enabled on the same pin at the same time. Do you see the spike if you don't initialize UART?

  • Sorry, you got me wrong. They were separate applications. We were able to implement UART Tx on pin 11 in a different application and PWM on pin 11 in a different application. 

    We never faced any error in prior cases as we never had the soft-on PWM functionality on reset. 

Reply Children
Related