int main(void) { ret_code_t err_code; /* 2-channel PWM, 200Hz, output on DK LED pins. */ app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(5000L, BSP_LED_0, BSP_LED_1); /* Switch the polarity of the second channel. */ pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH; /* Initialize and enable PWM. */ err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback); APP_ERROR_CHECK(err_code); app_pwm_enable(&PWM1); uint32_t value; while(true) { for (uint8_t i = 0; i < 40; ++i) { value = (i < 20) ? (i * 5) : (100 - (i - 20) * 5); ready_flag = false; /* Set the duty cycle - keep trying until PWM is ready... */ while (app_pwm_channel_duty_set(&PWM1, 0, value) == NRF_ERROR_BUSY); /* ... or wait for callback. */ while(!ready_flag); APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM1, 1, value)); nrf_delay_ms(25); } } }
/**@brief Function for initializing the PWM output */ static void pwm_init(void) { ret_code_t err_code; /* 1-channel PWM, 200Hz, output to pin 15 */ app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000L, BSP_LED_1); err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback); APP_ERROR_CHECK(err_code); /* Keep trying to set duty cycle until PWM ready */ while(app_pwm_channel_duty_set(&PWM1, 0, 100) == NRF_ERROR_BUSY); app_pwm_enable(&PWM1); }
static void pwm_reinit(pwm_t * pwm) { app_pwm_uninit(pwm->instance); app_pwm_config_t pwm_cfg = APP_PWM_DEFAULT_CONFIG_2CH(pwm->period_us, pwm->pins[0], pwm->pins[1]); app_pwm_init(pwm->instance, &pwm_cfg, NULL); app_pwm_enable(pwm->instance); for (uint8_t channel = 0; channel < PWM_CHANNELS_PER_INSTANCE; ++channel) { if ((pwm->channels_allocated & (1 << channel)) && (pwm->pins[channel] != APP_PWM_NOPIN)) { app_pwm_channel_duty_ticks_set(pwm->instance, channel, pwm->duty_ticks[channel]); } } }
static void ir_led_set_pwm(uint32_t physical_pin, uint32_t duty_cycle, uint32_t us_period) { //Uniniatialize PWM if there is any initialized. app_pwm_uninit(&pwm0); //Configuring PWM single channel. app_pwm_config_t pwm0_cfg = APP_PWM_DEFAULT_CONFIG_1CH(us_period, physical_pin); //Initializing PWM. APP_ERROR_CHECK(app_pwm_init(&pwm0, &pwm0_cfg, NULL)); //Enable PWM. app_pwm_enable(&pwm0); //Set duty cycle. while(app_pwm_channel_duty_set(&pwm0, 0, duty_cycle) == NRF_ERROR_BUSY); }
void pwmout_init(pwmout_t *obj, PinName pin) { if (pin == NC) { error("PwmOut init failed. Invalid pin name."); } // Check if pin is already initialized and find the next free channel. uint8_t free_instance = 0xFF; uint8_t free_channel = 0xFF; for (uint8_t inst = 0; inst < PWM_INSTANCE_COUNT; ++inst) { if (m_pwm[inst].channels_allocated) { for (uint8_t channel = 0; channel < PWM_CHANNELS_PER_INSTANCE; ++channel) { if (m_pwm[inst].channels_allocated & (1 << channel)) { if (m_pwm[inst].pins[channel] == (uint32_t)pin) { error("PwmOut init failed. Pin is already in use."); return; } } else { if (free_instance == 0xFF) { free_instance = inst; free_channel = channel; } } } } else { if (free_instance == 0xFF) { free_instance = inst; free_channel = 0; } } } if (free_instance == 0xFF) { error("PwmOut init failed. All available PWM channels are in use."); return; } // Init / reinit PWM instance. m_pwm[free_instance].pins[free_channel] = (uint32_t) pin; m_pwm[free_instance].duty_ticks[free_channel] = 0; if (!m_pwm[free_instance].channels_allocated) { NVIC_SetVector(GPIOTE_IRQn, (uint32_t) GPIOTE_IRQHandler); NVIC_SetVector(timer_handlers[free_instance].IRQn, timer_handlers[free_instance].vector); m_pwm[free_instance].period_us = PWM_DEFAULT_PERIOD_US; for (uint8_t channel = 1; channel < PWM_CHANNELS_PER_INSTANCE; ++channel) { m_pwm[free_instance].pins[channel] = APP_PWM_NOPIN; m_pwm[free_instance].duty_ticks[channel] = 0; } app_pwm_config_t pwm_cfg = APP_PWM_DEFAULT_CONFIG_1CH(PWM_DEFAULT_PERIOD_US, pin); app_pwm_init(m_pwm[free_instance].instance, &pwm_cfg, NULL); app_pwm_enable(m_pwm[free_instance].instance); } else { pwm_reinit(&m_pwm[free_instance]); } m_pwm[free_instance].channels_allocated |= (1 << free_channel); obj->pin = pin; obj->pwm_struct = (void *) &m_pwm[free_instance]; obj->pwm_channel = free_channel; }
// Application main function. int main(void) { uint32_t err_code; // set up timers APP_TIMER_INIT(0, 4, 4, false); // initlialize BLE ble_stack_init(); gap_params_init(); services_init(); advertising_init(); conn_params_init(); err_code = ble_advertising_start(BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); // init GPIOTE err_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(err_code); // init PPI err_code = nrf_drv_ppi_init(); APP_ERROR_CHECK(err_code); // intialize UART uart_init(); // prints to serial port printf("starting...\n"); // Create the instance "PWM1" using TIMER1. APP_PWM_INSTANCE(PWM1,1); // RGB LED pins // (Common cathode) uint32_t pinR = 1; uint32_t pinG = 2; uint32_t pinB = 3; // 2-channel PWM, 200Hz app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(5000L, pinR, pinG); /* Initialize and enable PWM. */ err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback); APP_ERROR_CHECK(err_code); app_pwm_enable(&PWM1); // Create the instance "PWM2" using TIMER2. APP_PWM_INSTANCE(PWM2,2); // 1-channel PWM, 200Hz app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000L, pinB); /* Initialize and enable PWM. */ err_code = app_pwm_init(&PWM2,&pwm2_cfg,pwm_ready_callback); APP_ERROR_CHECK(err_code); app_pwm_enable(&PWM2); // Enter main loop. int dir = 1; int val = 0; // main loop: bool pwmEnabled = true; while(1) { // only if not paused if (!pausePWM) { // enable disable as needed if(!enablePWM) { if(pwmEnabled) { app_pwm_disable(&PWM1); app_pwm_disable(&PWM2); // This is required becauase app_pwm_disable() // has a bug. // See: // https://devzone.nordicsemi.com/question/41179/how-to-stop-pwm-and-set-pin-to-clear/ nrf_drv_gpiote_out_task_disable(pinR); nrf_gpio_cfg_output(pinR); nrf_gpio_pin_clear(pinR); nrf_drv_gpiote_out_task_disable(pinG); nrf_gpio_cfg_output(pinG); nrf_gpio_pin_clear(pinG); nrf_drv_gpiote_out_task_disable(pinB); nrf_gpio_cfg_output(pinB); nrf_gpio_pin_clear(pinB); pwmEnabled = false; } } else { if(!pwmEnabled) { // enable PWM nrf_drv_gpiote_out_task_enable(pinR); nrf_drv_gpiote_out_task_enable(pinG); nrf_drv_gpiote_out_task_enable(pinB); app_pwm_enable(&PWM1); app_pwm_enable(&PWM2); pwmEnabled = true; } } if(pwmEnabled) { // Set the duty cycle - keep trying until PWM is ready while (app_pwm_channel_duty_set(&PWM1, 0, val) == NRF_ERROR_BUSY); while (app_pwm_channel_duty_set(&PWM1, 1, val) == NRF_ERROR_BUSY); while (app_pwm_channel_duty_set(&PWM2, 0, val) == NRF_ERROR_BUSY); } // change direction at edges if(val > 99) { dir = -1; } else if (val < 1){ dir = 1; } // increment/decrement val += dir*5; } // delay nrf_delay_ms(delay); } }