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

Unable to stop PWM

Hi guys,

I am now facing a problem that I can't stop the pwm by using nrf_drv_pwm_stop.

Here's my initial code for pwm and start the pwm in the while loop.

The output pin can complete generate the pulse 400Hz bit lust can't stop.

void PWM_Init(void)
{
    NRF_LOG_INFO("Demo 5");

    nrf_drv_pwm_config_t const motor_configure =
    {
        .output_pins =
        {
            PWM_pin | NRF_DRV_PWM_PIN_INVERTED,      // channel 0
            NRFX_PWM_PIN_NOT_USED,
            NRFX_PWM_PIN_NOT_USED,
            NRFX_PWM_PIN_NOT_USED					
           // BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
          //  BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
           // BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED  // channel 3
        },
        .irq_priority = APP_IRQ_PRIORITY_LOWEST,
        .base_clock   = NRF_PWM_CLK_1MHz,
        .count_mode   = NRF_PWM_MODE_UP,
        .top_value    = 2500,
        .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
        .step_mode    = NRF_PWM_STEP_AUTO
    };
    APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &motor_configure, NULL));
    m_used |= USED_PWM(0);
		printf("PWM Init successful \r\n");

}

void PWM_Start(void){
	    // This array cannot be allocated on stack (hence "static") and it must
    // be in RAM (hence no "const", though its content is not changed).
    static nrf_pwm_values_individual_t /*const*/ seq_values[] =
    {
        { 0x8000},
        {      0}
    };
    nrf_pwm_sequence_t const seq =
    {
        .values.p_individual = seq_values,
        .length              = NRF_PWM_VALUES_LENGTH(seq_values),
        .repeats             = 0,
        .end_delay           = 0
    };

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

void PWM_Stop(void){
	uint32_t err_code;
	//if (nrfx_pwm_is_stopped(&m_pwm0) != 1)
	err_code = nrf_drv_pwm_stop(&m_pwm0, true);
	
	if(err_code != NRF_SUCCESS){
		printf("motor stop failed  %d \r\n", err_code);
	}
}

    for (;;)
    {
			PWM_Start();
			nrf_delay_ms(500);
			PWM_Stop();
      idle_state_handle();
    }


The error code after calling nrf_drv_pwm_stop is one.

I can't recognize where the error it is.

Parents
  • Hello,

    Try to add a delay after PWM_Stop():

        for (;;)
        {
    		PWM_Start();
    		nrf_delay_ms(500);
    		PWM_Stop();
    		nrf_delay_ms(500);
    		
    		/* Application level interrupts may prevent this function 
    		 * from entering sleep. 
    		 */	
            idle_state_handle(); 
        }

    I don't see the implementation of idle_state_handle(), but I think what's happening in your program is that PWM_Stop() is immediately being followed by a call to PWM_Start(). nrfx_pwm_stop() is a boolean function and returns '1' when the PWM is stopped, so it's not returning any errors.

    Best regards,

    Vidar

Reply
  • Hello,

    Try to add a delay after PWM_Stop():

        for (;;)
        {
    		PWM_Start();
    		nrf_delay_ms(500);
    		PWM_Stop();
    		nrf_delay_ms(500);
    		
    		/* Application level interrupts may prevent this function 
    		 * from entering sleep. 
    		 */	
            idle_state_handle(); 
        }

    I don't see the implementation of idle_state_handle(), but I think what's happening in your program is that PWM_Stop() is immediately being followed by a call to PWM_Start(). nrfx_pwm_stop() is a boolean function and returns '1' when the PWM is stopped, so it's not returning any errors.

    Best regards,

    Vidar

Children
  • Hi Vidar,

    I just tried  nrfx_pwm_stop() but still didn't work.

    So I did another method to control the duty cycle.

    Here's my code below:

    void PWM_Init_Start(void)
    {
        NRF_LOG_INFO("Demo 5");
    
        nrf_drv_pwm_config_t const AFE4404_PWM_Config =
        {
            .output_pins =
            {
                Motor_pin | NRF_DRV_PWM_PIN_INVERTED, // channel 0
               // BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
              //  BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
               // BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED  // channel 3
            },
            .irq_priority = APP_IRQ_PRIORITY_LOWEST,
            .base_clock   = NRF_PWM_CLK_1MHz,
            .count_mode   = NRF_PWM_MODE_UP,
            .top_value    = 1,
            .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
            .step_mode    = NRF_PWM_STEP_AUTO
        };
        APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &AFE4404_PWM_Config, NULL));
        m_used |= USED_PWM(0);
    
    
    }
    
    void PWM_Start_Cycle(void){
    	    // This array cannot be allocated on stack (hence "static") and it must
        // be in RAM (hence no "const", though its content is not changed).
        static nrf_pwm_values_individual_t /*const*/ seq_values[] =
        {
            {      0},
            {      0},
    				{      0},
    				{      0},
    				{      0},
    				{      0},
    				{      0},
    				{      0},
    				{      0},
    				{ 0x8000}
        };
        nrf_pwm_sequence_t const seq =
        {
            .values.p_individual = seq_values,
            .length              = NRF_PWM_VALUES_LENGTH(seq_values),
            .repeats             = 0,
            .end_delay           = 0
        };
    
        (void)nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);
    }
    
    void PWM_Init_Stop(void)
    {
        NRF_LOG_INFO("Demo 5");
    
        nrf_drv_pwm_config_t const AFE4404_PWM_Config =
        {
            .output_pins =
            {
                Motor_pin | NRF_DRV_PWM_PIN_INVERTED, // channel 0
               // BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
              //  BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
               // BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED  // channel 3
            },
            .irq_priority = APP_IRQ_PRIORITY_LOWEST,
            .base_clock   = NRF_PWM_CLK_1MHz,
            .count_mode   = NRF_PWM_MODE_UP,
            .top_value    = 1,
            .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
            .step_mode    = NRF_PWM_STEP_AUTO
        };
        APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &AFE4404_PWM_Config, NULL));
        m_used |= USED_PWM(0);
    
    
    }
    
    void PWM_Stop_Cycle(void){
    	    // This array cannot be allocated on stack (hence "static") and it must
        // be in RAM (hence no "const", though its content is not changed).
        static nrf_pwm_values_individual_t /*const*/ seq_values[] =
        {
            { 0x8000},
            { 0x8000},
    				{ 0x8000},
    				{ 0x8000},
    				{ 0x8000},
    				{ 0x8000},
    				{ 0x8000},
    				{ 0x8000},
    				{ 0x8000},
    				{ 0x8000}
        };
        nrf_pwm_sequence_t const seq =
        {
            .values.p_individual = seq_values,
            .length              = NRF_PWM_VALUES_LENGTH(seq_values),
            .repeats             = 0,
            .end_delay           = 0
        };
    
        (void)nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);
    }
    
    void PWM_Start(void){
    	PWM_Init_Start();
    	PWM_Start_Cycle();
    }
    
    void PWM_Stop(void){
    	PWM_Init_Stop();
    	PWM_Stop_Cycle();
    }

    And I just combine the function into below:

    void mask_on(void){
    	PWM_Start();
    	nrf_delay_ms(2000);
    	PWM_Stop();	
    }

    But something weird is that when I call the mask_on in my main region, the pwm is on and off repeatedly.
    Are there any another way to stop the pwm?
  • Hi,

    Did you try to add the additional delay (nrf_delay_ms) in your original code like I suggested? I didn't mean to suggest that you should change the PWM_Stop() function.

Related