Vbat ──[R1 = 243 kΩ]──┬──[R2 = 10 kΩ]── GND
│
GPIO_45 / ADC0_CH3
&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 = ;
};
};
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 */
};
以下は、私たちが遭遇し、対処した問題点です。万が一、これらの問題が実際のバグや誤用を示している場合に備えて、ここに記載しておきます。
Zephyrドライバは、このSoC上でDTから/delete-property/ nxp,入力バッファ;をハードウェアに伝播しないため、ADC_REG_ANA[14]を直接クリアしました。
/* GAU_GPADC0 base 0x40038000, ADC_REG_ANA at offset 0x10 */ volatile uint32_t *p = (volatile uint32_t *)0x40038010; *p &= ~(1U << 14); /* clear INBUF_EN */
これがないと、入力バッファが高インピーダンス分圧器にバイアスをかけ、系統的なオフセットが生じる。
リセット時、SOCCIU_PAD_PU_PD_EN2 (SOCCTRL 非セキュアベース 0x45001000 のオフセット 0x78) のビット [27:26] = 01 → GPIO_45 で VDDIO への約 100 kΩ のプルアップが有効になっていました。9.6 kΩのテブナン電源では、これによりVadcは約200 mVオフセットされます。
nxp,mci-io-mux Zephyr pinctrlドライバはアナログピンのバイアス無効化プロパティを公開していないため、起動時に手動でビットをクリアします。
/* Clear GPIO_45 pad pull (PAD_PU_PD_EN2 bits [27:26]) */ volatile uint32_t *p = (volatile uint32_t *)0x45001078; *p &= ~(0x3U << 26);
この後、パッド上のマルチメーターは正確にVbat × 10 / 253(抵抗器の許容誤差の範囲内で約2%以内)を示すため、分圧器自体とパッドバイアスは正常であることがわかります。
診断目的のため、分圧器は(MOSFETを介してスイッチングされるのではなく)常時電源供給されているため、安定化の問題は発生しません。各ADCサンプリングの前に、マルチメーターを使用してパッド電圧が安定していることを確認します。
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)
以下のすべての組み合わせは、分圧器に常時電源を供給した状態でテストされ、マルチメーターによってアナログ入力が定常状態の期待値であることを確認しました。
ノブの値を試した結果、RAWに及ぼす影響
| VREF_SEL(参照) | 1.2 V (01) → 1.8 V (00) | RAW値は予想通り約1.2/1.8倍にスケーリングされるが、マルチメーターとの不一致は同じ係数で解消されない。 |
| INBUF_GAIN(ゲイン) | ゲイン=1 (01)、ゲイン=0.5 (00)、ゲイン=2 (10) | 効果なし— INBUF_EN=0 の場合、INBUF_GAIN は何も作用しないことを示唆しています。 |
| バイパス_ウォームアップ / ウォームアップ時間 | 0(バイパス)~最大32サイクル | RAWには測定可能な影響なし |
| ADC_CHOP_EN および INBUF_CHOP_EN | 両方ともオン、両方ともオフ | 無効 |
| Zephyr .calibrate | 真/偽 | 無効 |
上記すべてが正しそうに見えても、RAWは入力電圧を適切に追跡しません。測定シーケンス(Vbatは安定したベンチ電源から供給され、各ポイントでマルチメーターにより分圧器が検証されている):
| Vbat (V) | パッド(マルチメーター、mV) | パッドの期待値 = Vbat·10/253 (mV) | adc_read() からのRAWデータ |
| 22 | 848 | 869 | 1682 |
| 24 | 928 | 949 | 1708 |
| 26 | 1007 | 1028 | 2413 |
| 28 | 1084 | 1107 | 1745 |
| 29 | 1122 | 1146 | 1860 |
よろしくお願いします!
こんにちは、 @_arthur_ さん。お元気でお過ごしでしょうか。
これらのテストはどのZephyrバージョンで実施されたか、確認させていただけますでしょうか?Zephyrのバージョンに関してですが、弊社のダウンストリームリポジトリにZephyr 4.4.0がリリースされました。お客様が観察されている現象は、このバージョンでも発生するかどうかご確認いただけますでしょうか?
さらに、これらのテストはカスタムアプリケーションで実施しましたか?それとも、リポジトリの例から引用したものでしょうか?