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

nRF52840 SAADC Continuous sampling not started with TASK_START

When using the local timer of the SAADC it should be started with TASK_START according to https://infocenter.nordicsemi.com/topic/ps_nrf52840/saadc.html?cp=4_0_0_5_22_4#concept_continuous.

"The internal timer and the continuous sampling are started by triggering the START task and stopped using the STOP task."

However this doesn't work. TASK_SAMPLE is also required.

void SAADC_IRQHandler(void)
{
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_END)) {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG1, "NRF_SAADC_EVENT_END\n");

    }

    if (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED)) {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
        __LOG(LOG_SRC_APP, LOG_LEVEL_DBG1, "NRF_SAADC_EVENT_STARTED\n");
    }
}

void current_sensor_init(void) {
    nrf_saadc_resolution_set(NRF_SAADC_RESOLUTION_14BIT);
    nrf_saadc_oversample_set(NRF_SAADC_OVERSAMPLE_16X);
    nrf_saadc_continuous_mode_enable(16 * 16 * (2 + 3));

    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    nrf_saadc_int_enable(NRF_SAADC_INT_END);
    nrf_saadc_int_enable(NRF_SAADC_INT_STARTED);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);

    NRFX_IRQ_PRIORITY_SET(SAADC_IRQn, NRFX_SAADC_CONFIG_IRQ_PRIORITY);
    NRFX_IRQ_ENABLE(SAADC_IRQn);

    nrf_saadc_enable();

    nrf_saadc_channel_config_t config = {
            .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
            .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
            .gain       = NRF_SAADC_GAIN1_5,
            .reference  = NRF_SAADC_REFERENCE_INTERNAL,
            .acq_time   = NRF_SAADC_ACQTIME_3US,
            .mode       = NRF_SAADC_MODE_DIFFERENTIAL,
            .burst      = NRF_SAADC_BURST_ENABLED,
            .pin_p      = NRF_SAADC_INPUT_AIN3,
            .pin_n      = NRF_SAADC_INPUT_AIN4,
    };
    nrf_saadc_channel_init(0, &config);
    nrf_saadc_buffer_init(s_buf, 250);

    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
    //nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
}

In the above only NRF_SAADC_EVENT_STARTED is shown in the log.

If TASK_SAMPLE is triggered the NRF_SAADC_EVENT_END is also emitted to the log.

    nrf_ppi_channel_t ppi_saadc_end;

    APP_ERROR_CHECK(nrfx_ppi_channel_alloc(&ppi_saadc_end));
    APP_ERROR_CHECK(nrfx_ppi_channel_assign(
            ppi_saadc_end, nrf_saadc_event_address_get(NRF_SAADC_EVENT_END),
            nrf_saadc_task_address_get(NRF_SAADC_TASK_START)));
    nrf_ppi_channel_enable(ppi_saadc_end);

Connecting EVENT_END to TASK_START using PPI seem to be enough to keep the local timer running. But if TASK_CALIBRATEOFFSET is triggered after EVENT_END instead of TASK_START, TASK_SAMPLE is required to get the local timer to start sampling again.

I can't find anything related to this in the PS nor the Errata.

This was tested on the nRF52840-DK with an AAC0 variant. The same behavior was also seen on a nRF52833 AAA0 variant.

Thanks.

Parents
  • Hello,

    In the above only NRF_SAADC_EVENT_STARTED is shown in the log.

    If TASK_SAMPLE is triggered the NRF_SAADC_EVENT_END is also emitted to the log.

    You are correct - you will here need to also trigger the TASK_SAMPLE to actually begin the sampling. The TASK_START simply prepares the SAADC for work, and sets up the buffers in RAM.
    I see now that this is missing from both the API reference for the nrf_saadc_continuous_mode_enable function documentation, and the SAADC peripheral continuous mode documentation.
    I have made an internal ticket to our technical writers to have this reviewed. Thank you for bringing this up!

    Connecting EVENT_END to TASK_START using PPI seem to be enough to keep the local timer running. But if TASK_CALIBRATEOFFSET is triggered after EVENT_END instead of TASK_START, TASK_SAMPLE is required to get the local timer to start sampling again.

    This is as intended - calibration will stop all ongoing conversions, and they will need to be restarted following a successful calibration.
    Are you saying that you need to keep calling TASK_START after every EVENT_END? That does not sound right to me.
    Are you getting the EVENT_STOPPED following a EVENT_END?

    This was tested on the nRF52840-DK with an AAC0 variant. The same behavior was also seen on a nRF52833 AAA0 variant.

    If you here mean to say that you are working with an Engineering Version A variant of the nRF52840 SoC (DK version 0.9.x) then I highly recommend that you update your hardware to a non-engineering variant for future development.

    Thank you for bringing this to our attention!

    Best regards,
    Karl

Reply
  • Hello,

    In the above only NRF_SAADC_EVENT_STARTED is shown in the log.

    If TASK_SAMPLE is triggered the NRF_SAADC_EVENT_END is also emitted to the log.

    You are correct - you will here need to also trigger the TASK_SAMPLE to actually begin the sampling. The TASK_START simply prepares the SAADC for work, and sets up the buffers in RAM.
    I see now that this is missing from both the API reference for the nrf_saadc_continuous_mode_enable function documentation, and the SAADC peripheral continuous mode documentation.
    I have made an internal ticket to our technical writers to have this reviewed. Thank you for bringing this up!

    Connecting EVENT_END to TASK_START using PPI seem to be enough to keep the local timer running. But if TASK_CALIBRATEOFFSET is triggered after EVENT_END instead of TASK_START, TASK_SAMPLE is required to get the local timer to start sampling again.

    This is as intended - calibration will stop all ongoing conversions, and they will need to be restarted following a successful calibration.
    Are you saying that you need to keep calling TASK_START after every EVENT_END? That does not sound right to me.
    Are you getting the EVENT_STOPPED following a EVENT_END?

    This was tested on the nRF52840-DK with an AAC0 variant. The same behavior was also seen on a nRF52833 AAA0 variant.

    If you here mean to say that you are working with an Engineering Version A variant of the nRF52840 SoC (DK version 0.9.x) then I highly recommend that you update your hardware to a non-engineering variant for future development.

    Thank you for bringing this to our attention!

    Best regards,
    Karl

Children
No Data
Related