I am using SDK12.3.0 + SoftDevice S130 in nRF51 DK.
I create 4 channel PWM (+ppi) in timer1 & timer2, becauseI know timer0 is used by Softdevice, RTC1 by App_timer.
My problems is : When ever set PWM_B (using timer2) duty , app_timer stopped. ( log message stopped)
But if remark out the 2 lines "ctrl_pwm_duty_set(2,50); " & "ctrl_pwm_duty_set(3,80);", means not to set PWM_B (using timer2) duty, the code runs well.
For find out the root cause , I tried
1. Reduce PWM channel to 2 ( only use PWM_A) and change PWM_A timer resource from timer1 to timer2, the problem still happend (app_timer stopped). But if PWM_A use timer1, it has no problem. => Seems ONLY setting timer2 duty will cause app_timer stopped.
2. Exchange PWM_A and PWM_B using GPIOTE pin , problem still happen only when setting PWM_B (using timer2) duty => Seems not cause by GPIO pin.
I don't know why when setting PWM( using timer2 ) duty will cause app_timer stop. My project need to have 4 PWM channels and app_timer, Any idea about the root cause and how to solve it.
Thank you.
#define PIN_PWM_A1 25 #define PIN_PWM_A2 30 #define PIN_PWM_B1 24 #define PIN_PWM_B2 00 #define PWM_PERIOD 5000L //us APP_TIMER_DEF(m_local_timer_id); APP_PWM_INSTANCE(PWM_A,1); // Create the instance "PWM_A" using TIMER1. APP_PWM_INSTANCE(PWM_B,2); // Create the instance "PWM_B" using TIMER2. static void local_timer_event_handler(void * p_context) { NRF_LOG_DEBUG("APP_TIMER_EVENT\r\n"); } static void timers_init(void) { // Initialize timer module, making it use the scheduler APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false); uint32_t err_code; err_code = app_timer_create(&m_local_timer_id, APP_TIMER_MODE_REPEATED, local_timer_event_handler); APP_ERROR_CHECK(err_code); } void ctrl_pwm_init(void) { /* Initialize and enable PWM. */ app_pwm_config_t pwm_cfg_a = APP_PWM_DEFAULT_CONFIG_2CH(PWM_PERIOD, PIN_PWM_A1, PIN_PWM_A2); err_code = app_pwm_init(&PWM_A,&pwm_cfg_a,pwm_ready_callback); APP_ERROR_CHECK(err_code); app_pwm_config_t pwm_cfg_b = APP_PWM_DEFAULT_CONFIG_2CH(PWM_PERIOD, PIN_PWM_B1, PIN_PWM_B2); err_code = app_pwm_init(&PWM_B,&pwm_cfg_b,pwm_ready_callback); APP_ERROR_CHECK(err_code); app_pwm_enable(&PWM_A); app_pwm_enable(&PWM_B); } void ctrl_pwm_duty_set( uint8_t channel, app_pwm_duty_t duty) { if(channel <2) while(app_pwm_channel_duty_set(&PWM_A, channel, duty) == NRF_ERROR_BUSY); else while(app_pwm_channel_duty_set(&PWM_B, channel-2, duty) == NRF_ERROR_BUSY); } /**@brief Function for application main entry. */ int main(void) { ret_code_t err_code; // Initialize. err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); timers_init(); ble_stack_init(); gap_params_init(); services_init(); advertising_init(); conn_params_init(); ctrl_pwm_init(); ctrl_pwm_duty_set(0,10); ctrl_pwm_duty_set(1,30); //ctrl_pwm_duty_set(2,50); //ctrl_pwm_duty_set(3,80); advertising_start(); err_code = app_timer_start(m_local_timer_id, APP_TIMER_TICKS(1, 0), NULL); APP_ERROR_CHECK(err_code); // Enter main loop. for (;;) { if (NRF_LOG_PROCESS() == false) { power_manage(); } } }