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

About frequency drift on waveform generated by pwm driver during RF activities (i.e. Advertisement)

Hi,

I am using pwm driver to generate different square wave of different frequencies in order to drive a buzzer to play melody.

Below is how I init my pwm software module:

    nrf_drv_pwm_config_t const config0 =
    {
        .output_pins =
        {
            BUZZER_PWM | NRF_DRV_PWM_PIN_INVERTED,
            NRFX_PWM_PIN_NOT_USED,
            NRFX_PWM_PIN_NOT_USED,
            NRFX_PWM_PIN_NOT_USED
        },
        .irq_priority = APP_IRQ_PRIORITY_LOWEST,
        .base_clock   = NRF_PWM_CLK_1MHz,       
        .count_mode   = NRF_PWM_MODE_UP,
        .top_value    = melody_tone_list[0],
        .load_mode    = NRF_PWM_LOAD_WAVE_FORM,
        .step_mode    = NRF_PWM_STEP_AUTO
    };

    APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, pwm_handler));

Below is now I call start playing the melody:

(void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_pwm_seq1, memlody_tone_count, NRFX_PWM_FLAG_SIGNAL_END_SEQ0 | NRFX_PWM_FLAG_SIGNAL_END_SEQ1 | NRFX_PWM_FLAG_LOOP);

Below is how the pwm handler is:

It just update the m_pwm_seq1_values (next tone)either NRFX_PWM_EVT_END_SEQ0 or NRFX_PWM_EVT_END_SEQ1 event happened.

static void pwm_handler(nrf_drv_pwm_evt_type_t event_type)
{
    switch (event_type)
    {
      case NRFX_PWM_EVT_END_SEQ1:
      case NRFX_PWM_EVT_END_SEQ0:
      melody_tone_count = melody_tone_count -1;
      if (melody_tone_count > 0)
      {
          update_seq_values(event_type, &m_pwm_seq1, &m_pwm_seq1_values);
      }
      else
      {
          nrf_drv_pwm_uninit(&m_pwm0);
      }
      break;

      default:
      return;
    }
}

Since below is how I update the m_pwm_seq1_values in each event in pwm_handler. I also update the values of "repeats" in the m_pwm_seq1 so that the pwm keeps for specific time

m_pwm_seq_values.channel_0 = melody_tone_list[melody_tone_count] / 2;
m_pwm_seq_values.channel_1 = 0;
m_pwm_seq_values.channel_2 = 0;
m_pwm_seq_values.counter_top = melody_tone_list[melody_tone_count] / 2;           

And the m_pwm_seq1 is declared as below:

static nrf_pwm_sequence_t m_pwm_seq1 =
{
    .values.p_wave_form  = &m_pwm_seq1_values,
    .length              = NRF_PWM_VALUES_LENGTH(m_pwm_seq1_values),
    .repeats             = 0,
    .end_delay           = 0
};

If I just run it without having any RF activity, it seems good (I test it by generate a single pwm with a large "repeats" value). However, when I turn on the advertisement. I can hear the tone changing periodically and this tone changing period is aligned with the advertising interval.

Any idea what happen? And anyway to avoid this? If need to use other software module, please let me know.

Thank you.

Jones

Related