Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Invert PWM PIN, PWM, PWM intialize

I try to invert the Signal on a PIN of the PWM module 0. It sould give out the inverted Signal of another PIN from the same PWM module.

I tried it like the code below shows. Why does NRF_DRC_PWM_PIN_INVERTED doesn't have any influence?

nrf_drv_pwm_config_t const config0 =
{
.output_pins = {
OUTPUT_PIN | NRF_DRV_PWM_PIN_INVERTED, // channel 0 -- NRF_DRV_PWM_PIN_INVERTED seems to have no influence ?!!
OUTPUT_PIN_inv , // channel 1
// BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
// BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED // channel 3
},
.irq_priority = APP_IRQ_PRIORITY_LOWEST,
.base_clock = NRF_PWM_CLK_16MHz,
.count_mode = NRF_PWM_MODE_UP,
.top_value = TOPVAL,
.load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO
};
nrf_drv_pwm_init(&m_pwm0, &config0, &pwm_handler);

Thanks for replying

  • Hello,

     

    You are right. It looks like the NRF_DRV_PWM_PIN_INVERTED does not affect the pin at all. In fact, it doesn't while the PWM module is running. It only controls the pin when it is stopped (to keep any PWM device in a safe state).

     

    You might see in several of the demos that the number 0x8000 appears quite often. This is because the PWM module uses the 15th bit to determine whether the pin is active low or active high. So when the PWM module receives an input 0xNNNN, it is split in two. the first bit 0x8000 decides which state that is active high, and the other bits determines the length of the duty cycle.

     

    If you want to change one of the pins to be inverted e.g. in demo1, you must change the demo1_handler() to only check the 14 LSB. If you replace the demo1_handler with this, it should work:

     

    static void demo1_handler(nrf_drv_pwm_evt_type_t event_type)
    {
        if (event_type == NRF_DRV_PWM_EVT_FINISHED)
        {
            uint8_t channel    = m_demo1_phase >> 1;
            bool    down       = m_demo1_phase & 1;
            bool    next_phase = false;
    
            uint16_t * p_channels = (uint16_t *)&m_demo1_seq_values;
            uint16_t value = p_channels[channel] & 0x7FFF;
            if (down)
            {
                value -= m_demo1_step;
                if (value == 0)
                {
                    next_phase = true;
                }
            }
            else
            {
                value += m_demo1_step;
                if (value >= m_demo1_top)
                {
                    next_phase = true;
                }
            }
            p_channels[channel] = (p_channels[channel] & 0x8000) | value;
    
            if (next_phase)
            {
                if (++m_demo1_phase >= 2 * NRF_PWM_CHANNEL_COUNT)
                {
                    m_demo1_phase = 0;
                }
            }
        }
    }

    You can also remove the NRF_DRV_PWM_PIN_INVERTED, but it does not affect the pin when the PWM module is running.

     

    Best regards,

    Edvin

  • This one line explains lot ->

    seq_values->channel_0 = duty_cycle | 0x8000; :)
Related