I need to implement a 4kHz signal to drive a buzzer on a custom board of nRF51822 with external 16MHz and 32kHz crystal.
I am using Timer1+PPI+GPIOTE to generate this 4kHz signal.
Unfortunately there is sound distortion issue.
Measured by CRO, the 4kHz signal is jittering by 30us.
Below is the code I used to setup TIMER1 + PPI + GPIOTE.
Is there any thing I have missed to generate a stable 4kHz signal?
Thanks.
void timer_event_handler(nrf_timer_event_t event_type, void * p_context){ //For init only
}
void app_buzzer_init(){
uint32_t err_code;
uint32_t ret;
uint32_t time_ticks;
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(NRF_GPIOTE_INITIAL_VALUE_LOW);
err_code = nrf_drv_gpiote_out_init(BUZZER_PIN_0, &config);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_timer_init(&timer1, NULL, timer_event_handler);
APP_ERROR_CHECK(err_code);
time_ticks = (16000000 / m_main_params.buzzer_freq) / 2;
nrf_drv_timer_extended_compare(&timer1, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);
// Configure 1nd available PPI channel
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel1);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_assign(ppi_channel1,
nrf_drv_timer_event_address_get(&timer1, NRF_TIMER_EVENT_COMPARE0),
nrf_drv_gpiote_out_task_addr_get(BUZZER_PIN_0));
APP_ERROR_CHECK(err_code);
// Enable both configured PPI channels
err_code = nrf_drv_ppi_channel_enable(ppi_channel1);
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_out_task_enable(BUZZER_PIN_0);
nrf_drv_timer_disable(&timer1);
}
void buzzer_service(){
if (m_main_flag.buzzer_flag){
//edited: 2018/8/22
//=========Adding this part seems no change=========
NRF_CLOCK->TASKS_HFCLKSTART = 1;
/* Wait for the external oscillator to start up */
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
//==================================================
nrf_drv_gpiote_out_task_enable(BUZZER_PIN_0);
nrf_drv_timer_enable(&timer1);
}else{
nrf_drv_gpiote_out_task_disable(BUZZER_PIN_0);
nrf_drv_timer_disable(&timer1);
}
}
Board A, good sound and no jittering:
Board B, distorted sound with jittering (yellow marked = 30us):