Skip to content

Make oversampling work on LM20A - #117

Merged
lolren merged 2 commits into
lolren:mainfrom
hannesb:LM20-SAADC-Oversampling
Oct 15, 2026
Merged

lolren merged 2 commits into
lolren:mainfrom
hannesb:LM20-SAADC-Oversampling

Conversation

@hannesb

@hannesb hannesb commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Because the BURST control has moved to a separate register with nRF54LM20A, oversampling currently doesn't work with this chip. The patch fixed that.

Arduino sketch to test changes (tested with XIAO nRF54LM20A and XIAO nRF54L15):

#if !(defined(ARDUINO_NRF54LM20A) || defined(ARDUINO_NRF54LM20B) || defined(ARDUINO_NRF54L15))
#error "nRF54LM20A board required"
#endif

#include "nrf54l15_hal.h"

using namespace xiao_nrf54l15;

constexpr uint32_t kSaadcSpinLimit = 400000UL;

Saadc g_adc(nrf54l15::SAADC_BASE);

void setup() {
  Serial.begin(115200);
  delay(300);
  Serial.println(F("#### SAADC Oversampling Test ####"));
}

void loop() {
  // With oversampling
  int32_t u1 = 0, u2 = 0, u3 = 0;
  if (!g_adc.begin(AdcResolution::k14bit, AdcOversample::k256x, kSaadcSpinLimit)) {
    Serial.println("g_adc.begin() failed");
    while(1);
  }  
  g_adc.configureSingleEnded(0U, kPinD0, AdcGain::k2over8, 159, 4, true);
  g_adc.sampleMilliVolts(&u1, kSaadcSpinLimit);
  g_adc.configureSingleEnded(0U, AdcInternalInput::kAvdd, AdcGain::k2over8, 159, 4, true);
  g_adc.sampleMilliVolts(&u2, kSaadcSpinLimit);
  g_adc.configureDifferential(0U, kPinD0, kPinD1, AdcGain::k2over8, 159, 4, true);
  g_adc.sampleMilliVolts(&u3, kSaadcSpinLimit);

  // Without oversampling
  int32_t u4 = 0, u5 = 0, u6 = 0;
  if (!g_adc.begin(AdcResolution::k14bit, AdcOversample::kBypass, kSaadcSpinLimit)) {
    Serial.println("g_adc.begin() failed");
    while(1);
  }  
  g_adc.configureSingleEnded(0U, kPinD0, AdcGain::k2over8, 159, 4, false);
  g_adc.sampleMilliVolts(&u4, kSaadcSpinLimit);
  g_adc.configureSingleEnded(0U, AdcInternalInput::kAvdd, AdcGain::k2over8, 159, 4, false);
  g_adc.sampleMilliVolts(&u5, kSaadcSpinLimit);
  g_adc.configureDifferential(0U, kPinD0, kPinD1, AdcGain::k2over8, 159, 4, false);
  g_adc.sampleMilliVolts(&u6, kSaadcSpinLimit);

  Serial.printf("%ld,%ld,%ld,%ld,%ld,%ld\n", u1, u2, u3, u4, u5, u6);

  delay(100);
}

With Arduino serial plotter, one can easily see the less noisy signal with oversampling 😸

@lolren
lolren merged commit 9c77d9a into lolren:main Oct 15, 2026
@lolren

lolren commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Thanks for finding this and sharing the test sketch. I've included your contribution in 1.0.21, with the burst setting applied globally on LM20A and additional coverage for channels 1 and 7.

The connected LM20A passed three complete 36-case test sweeps. Could you give 1.0.21 another run on your L15 and LM20A when you have a chance?

Release and notes

@hannesb

hannesb commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

The connected LM20A passed three complete 36-case test sweeps. Could you give 1.0.21 another run on your L15 and LM20A when you have a chance?

I tested with 1.0.22, and oversampling works fine now on both XIAO nRF54L15 and nRF54LM20A.

Thx for your effort!
Hannes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants