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

Turn PWM off and back on

I am using Nordic SDK to develop an application. I need to turn PWM off and turn it back on (to produce a beeping sound from a buzzer). To do this I went into the bsp.c file and added the following code:
`
static uint32_t bsp_led_indication(bsp_indication_t indicate)
{
uint32_t err_code = NRF_SUCCESS;
uint32_t next_delay = 0;

    switch (indicate)
    { 
	case BSP_INDICATE_CONNECTED: // This case is used when a connection is made
            printf("BSP_INDICATE_CONNECTED\n");

            COMPONENTS_OFF(COMPONENTS_MASK & ~BSP_LED_0_MASK & ~ALERT_LED_MASK);
            COMPONENTS_ON(BSP_LED_0_MASK);

            
            beepCount++;
            if (beepCount <= 6) {
                
                printf("PWM init");
                ret_code_t err_code;
                app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(2000L, BSP_BUZZER);
                pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;

                // Initialize and enable PWM. 
                PWM1.p_cb->state = NRF_DRV_STATE_UNINITIALIZED;
                err_code = app_pwm_init(&PWM1,&pwm1_cfg,NULL);
                APP_ERROR_CHECK(err_code);
                app_pwm_enable(&PWM1);

                int dutyCycle;
                if (beepCount % 2 == 0) {
                    printf("high");
                    dutyCycle = 100;
                } else {
                    printf("low");
                    dutyCycle = 0;
                }

                app_pwm_channel_duty_set(&PWM1, 0, dutyCycle);
                app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(5000), NULL);
            }

            m_stable_state = indicate;
            break;
        default:
            break;
    }

    return err_code;
}

`

When I run this the application freezes the second time that it goes within the case BSP_INDICATE_CONNECTED (it only prints "PWM init" once). I turned on debugging but did not get a stack trace so I don't know how to debug this. My guess is that it is impossible to declare the PWM multiple times within the bsp_led_indication() without turning the previous PWM instance off.

One interesting side not is that if I comment out the APP_ERROR_CHECK the application doesn't freeze.

  • You should not place that functionality in the bsp module. Instead create a buzzer function in main.c, that you call when you get a BLE_GAP_EVT_CONNECTED in the function on_ble_evt():

    static void on_ble_evt(ble_evt_t * p_ble_evt)
    {
        uint32_t err_code;
    
        switch (p_ble_evt->header.evt_id)
                {
            case BLE_GAP_EVT_CONNECTED:
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
    	    buzzer();
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    

    Also set the duty cycle to 50 to make a sound, no reason to switch between 0 and 100. It also looks like you are initializing and enabling the pwm on every beep? If so, your code will run into the error handler.

Related