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

  • 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

  • Thanks, this observation is useful. I am trying to understand how the driver is working with this and it seems to be consistent of what you are saying.

    • calibrate = true is the only case where adc_read() runs through a multi-stage path: calibration must complete and fire CALIBRATEDONE, and only then does the driver start the actual conversion. The semaphore that adc_read() waits on is released only after that conversion finishes.
    • If the calibration step does not reach its CALIBRATEDONE callback, the conversion seems to be never started and adc_read() waits forever. The driver even has a branch that abandons the sequence without calling the callback if a STOP event arrives before CALIBRATEDONE.

    So this hang seems to be tied specifically to calibrate = true points to this calibration path, and it gives us a deterministic way to reproduce it, Once I reproduce this at my side, I will create an internal ticket and will try to see if I have the capability to debug it. I will treat this thread as a bug report.

Related