Marlin’s FastIO headers provide macros to read and change pin states as quickly as possible using direct port manipulation which is much faster than the Arduino.h functions. FastIO can only be used for pins defined as constants, and this is why Marlin currently uses hard-coded pin numbers and requires a re-compile when you want to change them.

FastIO Pin Mapping

Pins on an embedded processor aren’t just numbered sequentially. Instead they have a series of 8- or 16-bit wide “ports” with letter labels referred to by name as Port A, Port B, etc. A single bit in a port register might be a serial I/O line, a PWM signal, a simple digital pin that just holds its state, or any other imaginable function.

To make pins easier to manage for some processors, Marlin uses pin mappings that assign an index number to each digital I/O pin. For simplicity, these start with 0 to represent Port A Pin 0, 1 to represent Port A Pin 1, and so on, all the way up to 191 for Port L Pin 15.

To keep everything interoperable with the Arduino headers and documentation, Marlin uses the same mapping as the Arduino headers. All standard Arduino code uses the same mapping, which smartly uses the documented DIO pin numbers.

Note: Marlin code only uses digitalRead or digitalWrite in cases where the pin number is variable or unknown at compile-time.

AT90USB pins

Since version 1.1.4, Marlin also uses Arduino pin mapping for Teensy++, Sanguino, and other AT90USB-based processors, so we can still use the documented digital pin numbers even in the Teenyduino build environment. Previous versions of Marlin provided an option to use either Teensyduino or Arduino mapping, depending on the what the active pins file supported.

Analog pins

Analog inputs are always assigned using an index from 0-15. Marlin doesn’t need to know their digital pin numbers.

Marlin code should never use analogRead because it blocks execution. Instead, Marlin primes and reads one ADC input at a time, in sequence, at a rate of 500Hz divided by the number of analog devices. So, if you’ve got 2 thermistors and a filament width sensor, all three devices will be sampled at 166Hz.

LPC1768 / STM32 Pins

For LPC1768 and STM32 pins the documentation always refers to pins by their port number or port letter and the pin index within that port. So for LPC1768 the pins in Marlin are named like this: P0_03P4_14 . And for STM32 the pins in Marlin are named like this: PA3PD14. Of course, behind these names are index numbers, so those will also work.