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();
}
}
}