NRF54L15 ADC sampling gets stuck inside adc_read

Hi Dev,

Development platform: NRF54L15 + NCS 3.2.3

We are facing an issue with ADC sampling. The code occasionally gets stuck/hangs inside the adc_read function. This issue does not occur every time — it happens sporadically after long-term operation or under certain unknown conditions.

I have already narrowed down the issue and confirmed that the hang occurs inside adc_read.

Here is the code snippet:

c
int adc_single_channel_poll(uint8_t chan)
{
    if (chan >= ADC_CH_COUNT) return -EINVAL;

    int16_t             local_sample = 0;
    struct adc_sequence seq          = {
                 .channels    = BIT(channel_cfgs[chan].channel_id),
                 .buffer      = &local_sample,
                 .buffer_size = sizeof(local_sample),
                 .resolution  = 12,
    };

    int err = adc_read(adc_dev, &seq);

    if (likely(err == 0))
    {
        adc_raw[chan] = (local_sample < 0) ? 0 : local_sample;
    }

    return err;
}

The execution gets stuck at adc_read() and never returns.

Could you please help clarify:

  1. Is this a driver-layer bug in the ADC driver provided with NCS 3.2.3?

  2. Or could it be a hardware issue with the NRF54L15 device itself?

  3. Are there any known issues or errata related to ADC on NRF54L15 that could cause occasional hangs in adc_read?

Any suggestions on how to further debug or work around this issue would be greatly appreciated.

Thanks,
Chen

Parents
  • Sorry for late reply


    For the hang, what we know for sure is only that the ADC completion is never delivered, so adc_read() waits forever. There are three possible reasons that i can think of and the SAADC registers at the moment it hangs will tell us which:

    1. conversion never completed (EVENTS_END = 0), or
    2. it completed but was not serviced (EVENTS_END = 1).
    3. the interrupt was serviced and the event cleared, but a race in how the driver handles the event/state flags dropped the completion.

    Can you please capture EVENTS_END, EVENTS_STARTED, STATUS, INTENSET and RESULT.AMOUNT at the point it hangs? That will confirm which case it is.

    As a workaround, your approach is correct: set a finite ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT so adc_read() returns an error instead of hanging, and reinit the peripheral on that path (the driver does not clean it up on timeout).

    Once we know what happened here, we can try to see if this is a driver issue or something else.

Reply
  • Sorry for late reply


    For the hang, what we know for sure is only that the ADC completion is never delivered, so adc_read() waits forever. There are three possible reasons that i can think of and the SAADC registers at the moment it hangs will tell us which:

    1. conversion never completed (EVENTS_END = 0), or
    2. it completed but was not serviced (EVENTS_END = 1).
    3. the interrupt was serviced and the event cleared, but a race in how the driver handles the event/state flags dropped the completion.

    Can you please capture EVENTS_END, EVENTS_STARTED, STATUS, INTENSET and RESULT.AMOUNT at the point it hangs? That will confirm which case it is.

    As a workaround, your approach is correct: set a finite ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT so adc_read() returns an error instead of hanging, and reinit the peripheral on that path (the driver does not clean it up on timeout).

    Once we know what happened here, we can try to see if this is a driver issue or something else.

Children
No Data
Related