2361976_en-US

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2361976_en-US

2361976_en-US

RW612 GAU GPADC0 — inconsistent / non-monotonic readings on a high-impedance source

Setup

  • MCU: NXP RW612 on a Murata 2FR module
  • Software: Zephyr RTOS (GAU ADC driver adc_mcux_gau_adc)
  • ADC: GAU_GPADC0, base 0x40038000, channel 3 (single-ended) on GPIO_45
  • Use case: battery voltage monitoring, 22 V to 29 V range

Voltage divider on the analog input

  Vbat ──[R1 = 243 kΩ]──┬──[R2 = 10 kΩ]── GND
                          │
                         GPIO_45 / ADC0_CH3
  
  • Thevenin source impedance: ~9.6 kΩ
  • Expected pad voltage at Vbat = 25 V → 988 mV
  • Vbat range 22–29 V → pad range 869–1146 mV (well within Vref headroom)

Zephyr device-tree configuration

&adc0 {
      status = "okay";
      /delete-property/ nxp,input-buffer;   /* try to disable INBUF via DT */

      channel@3 {
          reg = <3>;
          zephyr,gain = "ADC_GAIN_1";
          zephyr,reference = "ADC_REF_INTERNAL";   /* maps to VREF_SEL=01 (1.2V) */
          zephyr,vref-mv = <1200>;
          zephyr,acquisition-time = ;
          zephyr,resolution = <12>;
          zephyr,input-positive = ;
      };
  };
  

Application-level configuration

static struct adc_channel_cfg channel_cfg = {
      .gain = ADC_GAIN_1,
      .reference = ADC_REF_INTERNAL,
      .acquisition_time = ADC_ACQ_TIME_DEFAULT,
      .channel_id = 3,
      .input_positive = 3,           /* GAU_ADC_CH3 */
  };

  static int16_t adc_buffer;
  static struct adc_sequence adc_seq = {
      .channels      = BIT(3),
      .buffer        = &adc_buffer,
      .buffer_size   = sizeof(adc_buffer),
      .resolution    = 12,
      .calibrate     = true,
      .oversampling  = 4,            /* 16x HW averaging */
  };
  

What I had to fix manually to get any sensible reading at all

These are issues we encountered and worked around — listed here in case any of them point to a real bug or a misuse:

1. INBUF_EN was never actually being cleared

The Zephyr driver does not propagate /delete-property/ nxp,input-buffer; from the DT into the hardware on this SoC, so we cleared ADC_REG_ANA[14] directly:

/* GAU_GPADC0 base 0x40038000, ADC_REG_ANA at offset 0x10 */
  volatile uint32_t *p = (volatile uint32_t *)0x40038010;
  *p &= ~(1U << 14);   /* clear INBUF_EN */
  

Without this, the input buffer biases the high-impedance divider and gives a systematic offset.

2. GPIO_45 default pad pull-up biases the divider node by ~200 mV

At reset, SOCCIU_PAD_PU_PD_EN2 (offset 0x78 of SOCCTRL non-secure base 0x45001000) had bits [27:26] = 01 → ~100 kΩ pull-up to VDDIO active on GPIO_45. On a 9.6 kΩ Thevenin source this offsets Vadc by ~200 mV.

The nxp,mci-io-mux Zephyr pinctrl driver does not expose a bias-disable property for analog pins, so we clear the bits manually at boot:

/* Clear GPIO_45 pad pull (PAD_PU_PD_EN2 bits [27:26]) */
  volatile uint32_t *p = (volatile uint32_t *)0x45001078;
  *p &= ~(0x3U << 26);
  

After this, the multimeter at the pad reads exactly Vbat × 10 / 253 (within ~2 %, consistent with resistor tolerance), so the divider itself and the pad biasing are now clean.

3. Settling / always-on divider

For diagnostic purposes, the divider is now permanently powered (instead of being switched via a MOSFET) so settling is not an issue. The pad voltage is verified stable with a multimeter before each ADC sample.

Verified register state at the time of measurement

GAU_GPADC0 (0x40038000):
    ADC_REG_ANA    [0x40038010] = 0x0000A810   → INBUF_EN=0, VREF_SEL=01 (1.2 V),
                                                 INBUF_GAIN=01, INBUF_CHOP_EN=1,
                                                 ADC_CHOP_EN=1, RES_SEL=00 (12-bit)
    ADC_REG_CONFIG [0x40038014] = 0x00000000

  MCI_IO_MUX (0x40004000):
    GPIO_GRP0      [0x40004030] = 0x001C1C02
    GPIO_GRP1      [0x40004034] = 0x201EDBD8

  SOCCIU PAD_PU_PD_EN2:
    [0x45001078] = 0x01152400                  → GPIO_45 PU/PD bits = 00 (no pull)
  

What I tried before posting

All combinations below were tested with the divider permanently powered, multimeter confirming the analog input is the steady-state expected value:

Knob Values tried Effect on RAW

VREF_SEL (reference)1.2 V (01) → 1.8 V (00)RAW scales by ~1.2/1.8 as expected, but the mismatch with the multimeter persists with the same factor
INBUF_GAIN (gain)gain=1 (01), gain=0.5 (00), gain=2 (10)No effect — suggests INBUF_GAIN does nothing while INBUF_EN=0
BYPASS_WARMUP / WARMUP_TIME0 (bypass) up to 32 (max) cyclesNo measurable effect on RAW
ADC_CHOP_EN & INBUF_CHOP_ENboth ON, both OFFNo effect
Zephyr .calibratetrue / falseNo effect

 

The remaining issue

Even with everything above looking correct, RAW does not track the input voltage in a sensible way. Sequence of measurements (Vbat fed by a stable bench supply, divider verified by multimeter at each point):

Vbat (V)Pad (multimeter, mV)Pad expected = Vbat·10/253 (mV)RAW from adc_read()
228488691682
249289491708
26100710282413
28108411071745
29112211461860

  • The multimeter column is monotonic and matches divider theory within ~2 %.
  • The RAW column is non-monotonic (jumps to 2413 at 26 V, then down to 1745 at 28 V).
  • Even ignoring the 2413 outlier, ΔRAW between 22 V and 28 V is only +63 LSB for +236 mV at the pad. With Vref = 1.2 V at 12-bit, expected ΔRAW ≈ 805 LSB. So the apparent gain is roughly 0.08× of theoretical — clearly wrong.
  • Earlier individual readings at single set-points had given RAW ≈ 2415 at Vbat ≈ 25 V (multimeter pad ≈ 990 mV), which would imply effective Vref ≈ 1.68 V instead of the configured 1.2 V — also unexplained.

 

My questions


  1. Is there any front-end attenuator or fixed gain on the GAU GPADC single-ended input path that is always active when INBUF_EN = 0, regardless of INBUF_GAIN? The ratio I'm seeing (~0.6 to 0.7×) is independent of VREF_SEL and INBUF_GAIN.
  2. Is INBUF_EN = 0 (direct sampling) actually a supported / characterized mode for single-ended measurements on RW612, or is it only valid for differential mode? The reference manual implies the input buffer should normally be enabled, but enabling it makes high-impedance sources unusable due to bias current.
  3. What is the maximum recommended source impedance for ADC0_CH3 in single-ended direct-sampling mode? Is 9.6 kΩ Thevenin acceptable or is an external buffer required?
  4. Is GPIO_45 a "special" channel (it can also carry EXT_VREF for external reference) — does the EXT_VREF analog path stay connected even when VREF_SEL = 01 (internal 1.2 V), and could it be loading the input?
  5. Are there any known errata or chopper-related artifacts on the GAU GPADC for high-impedance, low-frequency DC inputs?

Thanks!

Re: RW612 GAU GPADC0 — inconsistent / non-monotonic readings on a high-impedance source

Hello @_arthur_, hope you are doing well.

Would you please confirm in which Zephyr version have you done these tests? Regarding the Zephyr version, there is now available the release of Zephyr 4.4.0 of our downstream repository, would you please confirm if the behavior that you are observing is also present in this version?

Additionally, have you been doing these tests on a custom application? Or is it from a repository example?

タグ(1)
評価なし
バージョン履歴
最終更新日:
‎05-10-2026 02:46 AM
更新者: