The MCUXpresso Config Tools generate a pin_mux.c for every pin on the board in a few
clicks. Every pin gets a full pad configuration: pull, drive strength, slew rate and more.
That code compiles, it flashes, and for most pins it even works.
For a few pins it does not, and those failures are hard to trace back. A wrong pull direction does not cause a compiler error. It causes an SD card that mounts on one board and not on the next. The tool sets each field from the pin’s function. It knows nothing about the resistors on your schematic or the rules of the protocol on the wire.
In this article I go through what each pad-control field does, how to derive its value from the schematic and the protocol spec, and a microSD interface as a worked example.
1. What each field does
The mental model: every field answers one question about the wire, not about the peripheral.
Pull, keeper or neither (PKE, PUE)
This is the field people mix up most.
- Pull actively biases the line toward a rail through a real resistor. It holds that level even when nothing else drives the line.
- Keeper only latches the last driven level through a very weak feedback loop. It does not pull toward a fixed rail and does not fight an active driver. It just stops the line drifting between drive events.
- Disabled lets the pin float when nobody drives it. That is fine for a pin that is always driven by exactly one side, such as a clock output.
Pull value and direction (PUS)
Selects the internal resistor: on the RT1062 the choices are 100K Pull Down, 47K Pull Up,
100K Pull Up and 22K Pull Up. It only matters when the pin is set to Pull. It decides
the rest level of a line that can be undriven: tri-stated, open-drain, or an input with no
other bias.
Open drain (ODE)
Forces the output stage to open-drain: it only pulls low and never drives high, whatever the peripheral logic thinks it is doing.
- On for genuine wired-AND buses such as I²C, together with a pull-up.
- Off for push-pull signals such as SPI or SD. Turn it on there and the line never reaches a proper high level.
Drive strength (DSE)
Sets the output impedance as a fraction of a reference impedance R0, about 260 Ω at 3.3 V on
the RT1062. A larger divisor (R0/7) means a stronger driver: lower impedance, more current,
sharper edges.
- A long trace, a connector or several receivers need more drive to keep the edge clean at the far end.
- On a short trace to one receiver, more drive mostly adds ringing, overshoot and EMI, with no timing benefit.
Slew rate (SRE) and speed class (SPEED)
Slew rate sets how fast the output edge is, independently of drive strength. Fast is needed to meet timing at high clock rates; slow reduces overshoot and EMI. The speed field sets the pad’s frequency class.
Faster is not automatically better. Pick the slowest setting that still meets the timing at the frequency you actually run, not the peripheral’s theoretical maximum.
Hysteresis (HYS)
Switches the input buffer to a Schmitt trigger. Turn it on for mechanical switches, shared open-drain lines and any input with a slow or noisy edge. On a clean, fast, actively driven signal it buys nothing.
2. Derive the values from the schematic
The mental model: the schematic and the protocol spec decide; the tool only types it in.
For every pin, walk the same questions before you touch the config tool. The first “yes” decides the pull setting.
Never let an internal pull fight an external resistor
Two sources beat the schematic on their own:
- The protocol spec. Some interfaces require a pull direction that nothing on the schematic shows. The SD specification wants CMD and DAT pulled up, so they read high when nobody drives them.
- The state before software runs. An output that switches power or enables a load has no driver until the GPIO is initialised. Its pull setting decides what the load does during reset and boot, so pick the level that is safe.
3. Worked example: a microSD interface
A microSD socket wired directly to the USDHC pads shows all the rules at once:
- CLK, CMD and DAT0–3 go straight from the USDHC pads to the socket on short, single-load traces.
- Card detect (CD) has an external pull-up on the schematic. The card pulls it to ground when inserted.
Now suppose the generated configuration puts the same 100K Pull Down on every one of these
pins. The code builds and nothing complains, but three different things are now wrong:
Generated is not reviewed
4. The cheat sheet
Run through this before you press Generate:
| If the pin… | Then |
|---|---|
| is always driven by exactly one source (a clock, most outputs) | Pull/Keeper disabled |
| already has a pull resistor on the schematic | Internal pull disabled |
| must idle at a defined level (SD CMD/DAT, I²C, open-drain input) | Pull, in the required direction |
| is a bidirectional line that someone always drives | Keeper |
| is part of a wired-AND bus (I²C) | Open drain on, plus a pull-up |
| is a push-pull signal (SPI, SD) | Open drain off |
| runs over a long trace, a connector or to several loads | More drive strength |
| runs over a short trace to one load | Moderate drive strength |
| needs tight timing at a high clock rate | Fast slew, matching speed class |
| has timing margin to spare | Slow slew |
| comes from a switch or has a slow, noisy edge | Hysteresis on |
Summary
- Three fields can stop a peripheral outright: the pull direction, open drain, and to a lesser degree drive strength. The others trade timing margin against EMI.
- Derive each value from the wire: who drives the line, which resistors are already on it, what the protocol requires, and what the load needs before software runs.
- Generated code is a starting point. Review it against the schematic and the spec before the first board build, not after the first card fails to mount.
Sources
- NXP, i.MX RT1060 Processor Reference Manual, IOMUXC chapter:
SW_PAD_CTL_PAD_*fields. - NXP, i.MX RT1060 data sheet: pad drive strength and output impedance.
- SD Association, SD Specifications Part 1: Physical Layer Simplified Specification: pull-ups on CMD and DAT.
💬 Questions, corrections, or your own war story? Leave a comment below.
💬 Discussion
Questions, corrections, or war stories from your own board? Leave a comment below — I read and answer all of them. (Sign-in with GitHub.)