NetBurner 3.5.8
PDF Version
Analog to Digital (ADC)

Example Path: examples/PlatformSpecific/MODRT1171/ADC_Simple

Supported Platforms: MODRT1171

Simple A/D (ADC) Example for the MODRT1171

This example reads single-ended analog inputs on the MODRT1171 using the i.MX RT1171's two 12-bit LPADC modules, and shows how to measure 3.3V signals directly even though this platform's ADC reference is 1.65V. It converts a small set of channels once per second and prints the raw counts and voltage to the serial console.

Why the MODRT1171 ADC is Different From Other NetBurner Platforms

Other NetBurner platforms use a 3.3V ADC reference, so 0-3.3V maps to the full conversion range. The i.MX RT1171 handles this differently:

  • The LPADC reference (ADC_VREFH) is limited by the silicon to 1.0V - 1.89V (i.MX RT1171 datasheet, table 11). No reference selection (CFG[REFSEL]) allows a 3.3V reference; the only choices are the ADC_VREFH pin or the 1.8V analog supply (VDDA_ADC_1P8).
  • On the MODRT1171 module, ADC_VREFH is driven by an on-module precision shunt reference (TLVH431, +/-0.5%) set to 1.65V. The full-scale range of a plain conversion is therefore 0 - 1.65V.

Measuring 3.3V Signals – No External Circuitry Required

The LPADC includes a built-in input scaler (the CMDL[CSCALE] bit, selected per channel) that divides the input by 30/64 before conversion. With the module's 1.65V reference:

full scale = 1.65V * 64/30 = 3.52V

A 3.3V sensor or logic signal connects directly to the pin. This is not a trick: NXP characterizes the ADC in exactly this configuration (datasheet section 4.8.1, "VREFH = 1.68V, VADIN up to the GPIO supply rail"). The ADC input pins are in the GPIO_AD group, which is powered from the module's 3.3V I/O rail, so 3.3V on the pin is safe.

Each channel in this example selects one of two ranges:

Range Full scale Resolution Use for
AD_RANGE_1V65 1.65V 0.403 mV/LSB Small signals; best resolution
AD_RANGE_3V3 3.52V 0.859 mV/LSB 3.3V sensors and logic signals

Input limits:

  • Never exceed 3.6V on an ADC pin (GPIO_AD pad absolute maximum with the 3.3V I/O rail). In the 3.3V range, inputs between 3.52V and 3.6V simply read full scale (4095).
  • In the 1.65V range, inputs above 1.65V read full scale (4095); voltage up to 3.6V does not damage the pin.

When you DO need external circuitry:

  • Signals above 3.5V: use a resistor divider on the carrier board sized so the pin sees at most 3.3V (or 1.65V for the high-resolution range).
  • Keep the source impedance seen by the pin at or below 5 kOhm (datasheet limit). A high-impedance divider can be buffered with an op-amp, or compensated by increasing the sample time (sampleTimeMode in SimpleAD.cpp) and adding a capacitor from the pin to ground.

Available Channels on the Module Connectors

Single-ended inputs, 12-bit results. Each LPADC channel number has two independent single-ended inputs ("side" A and B).

LPADC1

Ch Side Pin Pad
0 A P1.27 GPIO_AD_06
0 B P1.26 GPIO_AD_07
1 A P1.29 GPIO_AD_08
1 B P1.12 GPIO_AD_09
2 A P1.15 GPIO_AD_10
2 B P1.14 GPIO_AD_11
3 A P1.17 GPIO_AD_12 *
3 B P1.16 GPIO_AD_13 *
4 A P1.19 GPIO_AD_14 *
4 B P1.18 GPIO_AD_15 *
5 A P1.21 GPIO_AD_16 *
5 B P2.6 GPIO_AD_17 *

LPADC2

Ch Side Pin Pad
0 A P2.7 GPIO_AD_18
0 B P2.8 GPIO_AD_19
1 A P2.10 GPIO_AD_20
1 B P2.11 GPIO_AD_21
2 A P2.12 GPIO_AD_22
2 B P2.13 GPIO_AD_23
3 A P1.17 GPIO_AD_12 *
3 B P1.16 GPIO_AD_13 *
4 A P1.19 GPIO_AD_14 *
4 B P1.18 GPIO_AD_15 *
5 A P1.21 GPIO_AD_16 *
5 B P2.6 GPIO_AD_17 *
6 A P2.4 GPIO_AD_24
6 B P2.3 GPIO_AD_25
  • GPIO_AD_12 - GPIO_AD_17 are routed to BOTH LPADC modules (channels 3-5). NXP recommends not converting these pins on both modules at the same instant (crosstalk; see AN14450). This example converts them from one module only.

Clocking (AN14450)

NXP application note AN14450 recommends clocking the ADCs from the internal RC oscillators rather than a PLL: all PLLs are phase-locked to the 24 MHz crystal, and an ADC clock phase-locked to the bus clock can make low-level synchronous digital noise show up as a repetitive signal in the ADC data. Using two different sources also removes a crosstalk mechanism between the two ADCs. This example uses:

LPADC1 <- OSC_RC_48M / 2 = 24 MHz
LPADC2 <- OSC_RC_400M / 8 = 50 MHz

(The valid ADC conversion clock range is 8 - 88 MHz.)

The SimpleAD API

Same pattern as the ADC examples on other NetBurner platforms (InitSingleEndAD / ADConfigCh / StartAD / ADDone / GetADResult):

Call Purpose
InitSingleEndAD() Set up clocks, reference, triggers
ADConfigCh(module, ch, side, range) Add a channel; configures the pin too
StartAD() Start converting all configured channels
ADDone() true when results are ready
GetADResult(module, ch, side) Raw 12-bit result (0 - 4095)
GetADVolts(module, ch, side) Result converted to volts at the pin

Each configured channel occupies one LPADC command buffer (up to 15 per module) and the buffers are chained, so StartAD() issues one software trigger per module and the hardware converts the whole list. Conversions use 16x hardware averaging and a 35-ADCK sample window (~40 us per channel); both are set in ADConfigCh() in SimpleAD.cpp and are easy to adjust.

Notes:

  • This part has no ADC calibration hardware (the LPADC auto-calibration functions are not available on the RT1171), so expect the datasheet's uncalibrated accuracy. The 16x averaging keeps noise low.
  • Differential conversions (A/B pin pairs) and hardware triggering via the ADC_ETC are supported by the silicon and the fsl_lpadc driver, but are beyond the scope of this example.

Running the Example

Voltages within each pin's range must be applied to the demo channels, or floating pins will read arbitrary values. The demo converts:

Pin Module Ch Side Range
P1.27 LPADC1 0 A 0 - 3.52V
P1.26 LPADC1 0 B 0 - 3.52V
P1.29 LPADC1 1 A 0 - 1.65V
P2.7 LPADC2 0 A 0 - 3.52V
P2.8 LPADC2 0 B 0 - 1.65V

Sample output (P1.27 tied to 3.3V, P1.29 tied through a divider to 0.825V):

Pin ADC Ch Range Raw Volts
-----------------------------------------
P1.27 1 0A 0-3.52V 3838 3.2989
P1.26 1 0B 0-3.52V 6 0.0052
P1.29 1 1A 0-1.65V 2049 0.8254
P2.7 2 0A 0-3.52V 3 0.0026
P2.8 2 0B 0-1.65V 1 0.0004

File Structure

ADC_Simple/
|
+-- src/
| +-- main.cpp Five-channel demo (UserMain)
| +-- SimpleAD.cpp LPADC setup and conversion (implementation)
| +-- SimpleAD.h Channel configuration and read API (declaration)
|
+-- makefile Build configuration (MODRT1171 only)
+-- ReadMe.txt This file
int read(int fd, char *buf, int nbytes)
Read data from a file descriptor (fd).