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

how to stop pwm and set pin to clear

Hi,all.i use pwm with sdk8.1 sample (SDK8.1\example\peripheral\pwm),my question is how to stop pwm and set the pin to low level? is my code correct? my pwm init code:


static uint32_t init_pwm(uint32_t perior,uint8_t pin)
 {	 
	 	uint32_t err_code = 0; 
    /* 2-channel PWM, 200Hz, output on DK LED pins. */
	  app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(perior, pin);
	 
	 pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
    
    /* Initialize and enable PWM. */
    err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
    APP_ERROR_CHECK(err_code);

    return err_code;
}
------------------------------------------------------------------------------

pwm stop code:
void pwm_stop( void )
{
   app_pwm_disable(&PWM1);
}
----------------------------------------------------------------------------

pwm start code:
void pwm_start( void )
{   
   app_pwm_enable(&PWM1);
}
  • Hi wuvo, I have noticed that app_pwm library does not disable a GPIOTE config, which means that it does not free the pin from gpiote after you are done. I created a ticket for it for the team.

    For your code you can do this.

    1. before initializing pwm library, you configure the pin through gpio interface

      nrf_gpio_pin_dir_set(pin_number, NRF_GPIO_PIN_DIR_OUTPUT); nrf_gpio_pin_clear(pin_number);

    2. Then you initialize PWM using app_pwm library, do your stuff

    3. in your pwm_stop add three lines to it

      void pwm_stop( void ) { app_pwm_disable(&PWM1); nrf_drv_gpiote_out_task_disable(pin_number); nrf_gpio_cfg_output(pin_number) nrf_gpio_pin_clear(pin_number); }

    Now as soon as the pin is freed by nrf_drv_gpiote_out_task_disable then gpio configuration will take into effect.

    EDIT: 10.08.2015

    PAN-73 workaround is enabled by default in app_pwm_init

    PAN-73 workaround is disabled in app_pwm_uninit

    This means there will be increase in power consumption (~50uA) if the PAN-72 workaround is enabled.

    Check here

  • void pwm_start( void ) {
    nrf_drv_gpiote_out_task_enable(pin_number); app_pwm_enable(&PWM1); }

  • Thanks,Aryan.i tested as what your say,but the pin is high level always.no effects.i want to controll buzzer used pwm.what's wrong?i reconfig pwm before i start(restart) pwm using code as follow:

    -------------------------------------------------------------------------
    uint32_t reconfig_pwm(uint32_t perior,uint8_t pin)
    {
    	uint32_t err_code = 0;
    
    	err_code = app_pwm_uninit(&PWM1); 	
    	APP_ERROR_CHECK(err_code);
    
    	if( err_code == NRF_SUCCESS)
    	{
    	  err_code =	init_pwm(perior,pin);
    		APP_ERROR_CHECK(err_code);
    	}
    	
    	//while (app_pwm_channel_duty_set(&PWM1, 0, 50) == NRF_ERROR_BUSY);
    
    	return err_code;
    
    }
    
    static uint32_t init_pwm(uint32_t perior,uint8_t pin)
     {	 
    	 	uint32_t err_code = 0;
    
    		nrf_gpio_pin_dir_set(pin, NRF_GPIO_PIN_DIR_OUTPUT);
    		nrf_gpio_pin_clear(pin);
    	 
        /* 2-channel PWM, 200Hz, output on DK LED pins. */
    	  app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(perior, pin);
    	 
    	 pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
        
        /* Initialize and enable PWM. */
        err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
        APP_ERROR_CHECK(err_code);
    
        return err_code;
    }
    ------------------------------------------------------------------------------------------------
    then,start it:
    void pwm_start( void )
    {   
       app_pwm_enable(&PWM1);
    	 while (app_pwm_channel_duty_set(&PWM1, 0, 50) == NRF_ERROR_BUSY);
    }
    -----------------------------------------------------------------------------------------------
    stop as this:
    void pwm_stop( void )
    { 
    	  app_pwm_disable(&PWM1);
    	  nrf_drv_gpiote_out_task_disable(SPEAKER_PIN);
              nrf_gpio_pin_clear(SPEAKER_PIN);
    
    //	  while (app_pwm_channel_duty_set(&PWM1, 0, 0) == NRF_ERROR_BUSY);
    	  pos = 0;
    	  time = 0;
    	  k = 0;
    	  freq = 0;
    }
    
  • That should have worked, If this does not work then it means that somewhere GPIOTE still owns the pin.

    nrf_drv_gpiote_out_task_disable(SPEAKER_PIN);
    nrf_gpio_cfg_output(SPEAKER_PIN);
    nrf_gpio_pin_clear(SPEAKER_PIN);
    
Related