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
  • Maybe my observation helps the investigation. I'm using nRF52832 with NCS v3.1.1.

    For me adc_read() gets stuck if I set adc_sequence::calibrate to true before calling adc_sequence_init_dt() and adc_read(). As long as we don't try to calibrate, reading the channel works as expected.

    Our calibration approach/procedure was working on older versions of NCS (I can't investigate right now on which version it started to fail).

  • So I added some logging (actually I send the values over BLE, because I can't reproduce the issue in a debug build with logging) and here are my results. To note: I set the ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT to 10 milliseconds (because when measureing every millisecond this is already quite long I think).
    Values are decimal.

    The events all happend during one active cycle - I don't have exact timestamps, but they should be very close. But there are also a lot of cycles without any failures (1 cycle takes about 430 milliseconds). I guess not every one of those adc-calls really hangs - maybe I should try it with a higher timeout?

    EVENTS_END;EVENTS_STARTED;STATUS;INTENSET;RESULT.AMOUNT;EVENTS.CALIBRATION_DONE
    0;0;0;35;4;0
    0;0;1;35;0;0
    0;0;1;35;4;0
    0;0;1;35;4;0
    0;0;1;35;4;0
    0;0;1;35;4;0
    0;0;1;35;4;0
    0;0;1;35;4;0

    I also tried a timeout of 10 milliseconds with the same results.

    I hope you can make something out of this!
    Best regards
    Marco

Related