nRF5 SDK is not maintained anymore
More Info: Consider nRF Connect SDK for new designs

NRF52840 dongle PWM signals with arbitrary phase-shift and duty cycle

Hi,

I am merging a PWM_driver example with a ble-peripheral-blinky example to generate PWM signals with user-defined arbitrary phase-shift and duty cycle.

I am done with the ble part that I can set arbitrary duty cycles using an android application. 

However, the problem is that no matter if I use | 0x8000 or the NRF_DRV_PWM_PIN_INVERTED flag, the polarity of my pin does not change and I cannot see any polarity change in the oscilloscope. I am using an nrf52840 dongle.

I plan two build two PWM signals that the user is able to change not only the duty cycle of that but also make an arbitrary phase-shift between the two signals.

Could you guys help me with the polarity problem?
Besides, any suggestion regarding the phase shift and how to build that would be appreciated.

Also, if there is a command to define a dead-time between the PWM signals using PWM_driver, that would be awesome.

Thanks,

  • Hi

    Could you add an image of the pwm signal you send?

    Are you able to change the duty cycle of the PWM?

    Regards,
    Sigurd Hellesvik

  • Yes, I am able to change the duty cycle. The problem is with the polarity!

    here is the my two signals that I am created for the the following commands, but as you can see, the polarity of the two signals are the same, unexpectedly!

    As you can see, the duty cycle works, but making it OR with 0x8000 will not convert the polarity of the pin!

    thanks

  • Hi

    If we have a look at the nrfx_pwm_init function, we can see that the p_configure->output_pin is only used in configure_pins:

    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);
    }

    It looks like NRF_DRV_PWM_PIN_INVERTED only sets the start value of the pin, and not the Polarity.

    To set the polarity, you likely need to look into nrf_pwm_sequence_t.
    From its documentation:
    " In each value, the most significant bit (15) determines the polarity of the output and the others (14-0) compose the 15-bit value to be compared with the pulse generator counter. "

    An example on how to use this sequence struct can be seen in for example demo3 in the examples/peripheral/pwm_driver.

    Are you able to set polarity using this method?

    Regards,
    Sigurd Hellesvik

  • In each value, the most significant bit (15) determines the polarity of the output and the others (14-0) compose the 15-bit value to be compared with the pulse generator counter.

    To do this, as you can see in my previous reply and the first picture, I add | 0x8000 to the sequence to change the polarity, but as is shown in the second picture the polarity is not changed! So, the Demo3, that you mentioned, does not work for changing the polarity, as it is also using the 0x8000 command. Using just 0x8000 changes the duty cycle.

    The following link shows the exact code that I am using for changing polarity and the duty cycle but it does not work for the polarity:

    https://jimmywongiot.com/2021/06/01/advanced-pulse-width-modulation-pwm-on-nordic-nrf52-series/
      

Related