Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Interaction between timer and saadc

I'm writing software for nRF52832 using nRF5 SDK v17.0.2

I'm using a timer to create a buzz/tone using timer 3.    This works as expected.

I'm also using the SAADC to measure the voltage on input pin AIN3.   Since I only need this value occasionally, I only call the ADC conversion when needed.   Here is the code:

//
// ADC for voltage measurement
//
void saadc_callback(nrfx_saadc_evt_t const * p_event) {
  NRF_LOG_INFO("ADC event");
}

void
saadc_init(void) {
  ret_code_t err_code;

  //err_code = nrf_drv_saadc_init(NULL, saadc_callback);
  //APP_ERROR_CHECK(err_code);
  nrfx_saadc_config_t adcConfig;
  adcConfig.low_power_mode     = true;
  adcConfig.resolution         = NRF_SAADC_RESOLUTION_12BIT;
  adcConfig.oversample         = NRFX_SAADC_CONFIG_OVERSAMPLE;
  adcConfig.interrupt_priority = APP_IRQ_PRIORITY_LOW;
  err_code = nrfx_saadc_init(&adcConfig, saadc_callback);
  APP_ERROR_CHECK(err_code);

  // Configure channel 0
  nrf_saadc_channel_config_t channelConfig0;
  channelConfig0.reference     = NRF_SAADC_REFERENCE_INTERNAL;
  channelConfig0.gain          = NRF_SAADC_GAIN1_6;
  channelConfig0.acq_time      = NRF_SAADC_ACQTIME_10US;
  channelConfig0.mode          = NRF_SAADC_MODE_SINGLE_ENDED;
  channelConfig0.burst         = NRF_SAADC_BURST_DISABLED;
  channelConfig0.pin_p         = VBATT_PIN;   // AIN3 = P0.05
  channelConfig0.pin_n         = NRF_SAADC_INPUT_DISABLED;
  channelConfig0.resistor_p    = NRF_SAADC_RESISTOR_DISABLED;
  channelConfig0.resistor_n    = NRF_SAADC_RESISTOR_DISABLED;
  // Configure Channel 0
  err_code = nrfx_saadc_channel_init(0, &channelConfig0);
  APP_ERROR_CHECK(err_code);
}


nrf_saadc_value_t
getBattVoltage(void) {
  ret_code_t err_code;
  nrf_saadc_value_t sample;

  // Sample channel 0
  err_code =nrfx_saadc_sample_convert(0, &sample);
  APP_ERROR_CHECK(err_code);

  return sample;
}

Since I'm not continuously sampling the ADC, no timer was set up for it.   Is the ADC set up and being used properly?

When the "saadc_init" function executes, the tone generation no longer works.    If I comment out the call to "saadc_init" (obviously the ADC can't be used), the tone generator works.

I didn't see anything in the documentation that mentions any interaction/dependency between the saadc and timer 3.

Did I miss something?

Thanks!

Parents
  • When the "saadc_init" function executes, the tone generation no longer works.

    Are you sure the code is not asserting? If you build with Debug (not Release) you may get more information about the assert in app_error_fault_handler().

  • Some additional information:   saadc_init (see above) really only has two actions:  initializing the saadc block and initializing the individual input channel.

    If I comment out the initialization of the individual channel, then the buzzer (using timer 3) works.

    So the initialization of the actual saadc block seems to be OK.

    The individual ADC input is using Pin P0.05 (AIN3)

    The buzzer output is using Pin P0.28 (AIN4) configured as an Output.     Is there some rule that I'm missing about not using the Analog pins for normal GPIO outputs when using other Analog pins as inputs to SAADC?

Reply
  • Some additional information:   saadc_init (see above) really only has two actions:  initializing the saadc block and initializing the individual input channel.

    If I comment out the initialization of the individual channel, then the buzzer (using timer 3) works.

    So the initialization of the actual saadc block seems to be OK.

    The individual ADC input is using Pin P0.05 (AIN3)

    The buzzer output is using Pin P0.28 (AIN4) configured as an Output.     Is there some rule that I'm missing about not using the Analog pins for normal GPIO outputs when using other Analog pins as inputs to SAADC?

Children
Related