Verifying correct pin-to-pin connections and interface signal integrity at the schematic level
Pin-to-pin verification means comparing every connection on the schematic against the official component datasheet pin descriptions. This catches swapped pins, connections to wrong pin functions, and mismatches between the schematic symbol and the actual IC pinout. It is the most fundamental connectivity check and catches the most expensive errors.
Never trust schematic symbols blindly - always verify against the manufacturer's datasheet pinout diagram.
A single swapped pin (TX/RX reversed, MISO/MOSI swapped, or address bit miswired) renders the board non-functional for that interface. These errors cannot be fixed in firmware and typically require a board respin. A wrong symbol in the library (pins numbered incorrectly) propagates the error to every design using that symbol. Pin-swap errors are the #1 cause of first-board-doesn't-work situations.
SPI connection verification:
STM32F407 (Master) W25Q128 Flash (Slave)
Pin 30 (PA5/SPI1_SCK) --> Pin 6 (CLK) [Clock: Master out, Slave in]
Pin 31 (PA6/SPI1_MISO) <-- Pin 2 (DO) [Data: Slave out, Master in]
Pin 32 (PA7/SPI1_MOSI) --> Pin 5 (DI) [Data: Master out, Slave in]
Pin 29 (PA4/GPIO) --> Pin 1 (nCS) [Chip select: Active low]
Verified against: STM32F407 datasheet Table 9 (Alternate Functions)
W25Q128JV datasheet Figure 1 (Pin Configuration)
Both pin numbers AND signal directions confirmed correct.
Symbol pin error: Schematic symbol for W25Q128 was created with pins 2 and 5 swapped (DO and DI reversed). Schematic LOOKS correct (MOSI->DI label, MISO->DO label) but physical pin 2 is actually DO and pin 5 is DI. The PCB traces connect correctly to the wrong physical pins. Board fabricated, flash chip does not respond. $8,000 board respin required.
KiCad: Compare symbol against datasheet in Symbol Editor (Edit > Symbol). Check pin mapping in Footprint Assignment. Use 3D viewer to verify physical pin positions.
Altium: Use Component Wizard to verify pin-to-pad mapping. Cross-probe between schematic and PCB. Verify with Manufacturer links in component properties.
OrCAD: Open Part Editor to verify pin numbers vs. package. Use cross-reference between schematic symbol and PCB footprint padstack.
Open-drain (or open-collector) outputs can only pull a signal LOW - they cannot drive HIGH. These outputs require an external pull-up resistor to the appropriate voltage rail to define the HIGH state. Without the pull-up, the signal floats when the output is inactive. Common open-drain signals include I2C (SDA, SCL), interrupt outputs (nIRQ), power-good indicators (nPGOOD), and status flags.
The pull-up resistor value determines the rise time, power consumption, and noise immunity of the signal.
An open-drain signal without a pull-up resistor will never go HIGH - it floats at an undefined voltage. For I2C, this means the bus never releases and communication fails completely. For interrupt lines, the MCU sees constant triggering from noise on the floating line, causing 100% CPU utilization processing false interrupts. For PGOOD signals, the MCU cannot detect when power is stable, preventing proper boot sequencing.
I2C bus pull-ups:
Bus: I2C1 at 400kHz (Fast Mode) Devices: STM32 (master), BME280 (slave), EEPROM AT24C256 (slave) Bus capacitance: ~50pF (estimated from trace length and device pin capacitance) Pull-up rail: VCC_3V3 Pull-up calculation: R_min = (VCC - VOL_max) / IOL = (3.3 - 0.4) / 3mA = 967 ohms (minimum) R_max = tr_max / (0.8473 * Cb) = 300ns / (0.8473 * 50pF) = 7.08k (maximum for 400kHz) Selected: 4.7k (within 967 ohms to 7.08k range) Rise time: 0.8473 * 4.7k * 50pF = 199ns (meets 300ns max for Fast Mode) R_SDA = 4.7k to VCC_3V3 R_SCL = 4.7k to VCC_3V3
Missing I2C pull-ups: Engineer connects I2C SDA and SCL between STM32 and BME280 sensor with no pull-up resistors, relying on "internal pull-ups" in the STM32. STM32 internal pull-ups are typically 30k-50k ohms. At 400kHz with 50pF bus capacitance, rise time = 0.8473 * 40k * 50pF = 1.7us. Required maximum rise time for 400kHz: 300ns. Bus is 5x too slow. Communication works unreliably - occasional NACK errors, data corruption, sometimes OK (marginal timing).
KiCad: Search for open-drain symbols in schematic. Check net connections for pull-up resistors. ERC can flag nets with only open-drain drivers and no passive pull-up.
Altium: Use Net Classes to group I2C signals. Signal Integrity analysis shows if rise times meet specifications with current pull-up values.
OrCAD: Use DRC rules to check for pull-ups on nets connected to open-drain pins. Custom design rules can flag missing pull-ups.
Every digital input pin that is not used in the design must be tied to a defined logic level (VCC or GND) either directly or through a resistor. This includes unused gate inputs on logic ICs, unused select pins on multiplexers, unused address pins on I2C devices, and unused GPIO configured as inputs on MCUs. The correct tie level is specified in the component datasheet.
This is closely related to the "no floating pins" check but focuses specifically on active IC inputs that could cause functional issues.
CMOS input pins have extremely high impedance (>1M ohm). A floating CMOS input acts as an antenna, picking up electromagnetic noise which causes the input to oscillate between HIGH and LOW states at radio frequencies. This causes: excessive power consumption (both P and N transistors conducting simultaneously = shoot-through current), EMI radiation from the oscillating internal circuitry, unpredictable logic behavior downstream, and potential latch-up in extreme cases.
74LVC14 hex inverter (only 4 of 6 used):
Used: Inputs 1A, 2A, 3A, 4A connected to signal sources Unused: Pin 9 (5A input) --> tied to GND through 10k resistor Pin 11 (6A input) --> tied to GND through 10k resistor Pin 8 (5Y output) --> left unconnected (outputs can float safely) Pin 10 (6Y output) --> left unconnected Rationale: Inputs tied LOW to prevent oscillation. 10k resistor allows future rework if input is needed later. Outputs left open (driving nothing consumes no extra power).
74HC14 with floating inputs: Only 2 of 6 inverters used. Four input pins (3A, 4A, 5A, 6A) left floating. Each unused inverter oscillates at ~40MHz (input noise bandwidth), drawing 5mA per gate = 20mA additional current (vs. 1uA spec quiescent). Total IC power: 70mW instead of 0.01mW. Adds significant switching noise to power rail. EMI scan shows 40MHz harmonic spikes radiating from the IC. Board fails FCC testing.
KiCad: ERC flags unconnected input pins. Place No-Connect flag (X) only on OUTPUTS. For inputs, always provide a connection. Review ERC input pin warnings carefully.
Altium: ERC marks unconnected input type pins. Use "No ERC" directive only after confirming the pin is properly handled. Compile to see all unconnected pins.
OrCAD: DRC checks for undriven inputs. Mark unused inputs with explicit connections to power/ground in schematic. Don't use No-DRC markers on inputs.
Modern MCUs and SoCs have pins that serve multiple functions (GPIO, SPI, I2C, UART, PWM, ADC) selectable through configuration registers. The schematic must correctly map signals to pins that actually support the required alternate function. Not every pin supports every function - the alternate function mapping table in the datasheet defines which functions are available on which pins.
Additionally, some pins have configuration strapping (boot mode, bus width) that must be set correctly at power-up via pull-up/pull-down resistors.
If UART1_TX is connected to a pin that only supports SPI and GPIO (not UART), the interface will never work regardless of firmware configuration. This error cannot be fixed with software - it requires a board respin to move the trace to a pin that supports the UART alternate function. Similarly, incorrect boot strapping pins can prevent the MCU from starting (wrong boot mode, incorrect bus width for external memory).
STM32F407 peripheral mapping verification:
Required: SPI1, I2C1, USART2, 3x ADC channels, 2x PWM outputs PA5 = SPI1_SCK (AF5 - verified in Table 9) PA6 = SPI1_MISO (AF5 - verified) PA7 = SPI1_MOSI (AF5 - verified) PB6 = I2C1_SCL (AF4 - verified, pin supports I2C with internal OD) PB7 = I2C1_SDA (AF4 - verified) PA2 = USART2_TX (AF7 - verified) PA3 = USART2_RX (AF7 - verified) PA0 = ADC1_IN0 (analog mode - verified, pin has ADC channel) PA1 = ADC1_IN1 (analog mode - verified) PC0 = ADC1_IN10 (analog mode - verified) PB0 = TIM3_CH3 (AF2 - verified for PWM output) PB1 = TIM3_CH4 (AF2 - verified for PWM output) No conflicts detected. All AF assignments verified against datasheet.
Pin function conflict: Designer connects UART1_TX to pin PC6 and Timer8_CH1 PWM output to the same PC6. Both cannot be active simultaneously (same AF number conflict). Also: ADC input connected to PB2 which has NO ADC channel (PB2 is BOOT1 pin with no ADC alternate function). Design requires board respin to move ADC to a pin with actual ADC capability (PA0-PA7, PC0-PC5).
KiCad: Use STM32CubeMX or chip-specific pin planning tools to verify pin assignments BEFORE creating the schematic. Export pin configuration to match schematic.
Altium: Many MCU manufacturers provide Altium-compatible pin planning tools. Import pin mapping directly into component properties.
OrCAD: Use manufacturer's pin planning tool (STM32CubeMX, NXP MCUXpresso Config Tools) and cross-reference with schematic connections.
I2C devices share a bus using 7-bit addresses. If two devices have the same address, they both respond simultaneously, corrupting data. Address conflicts occur when using multiple copies of the same sensor or when different ICs happen to share the same default address. SPI avoids this with chip-select lines, but those must be unique per device. Address checking verifies no two devices on the same bus will collide.
Some I2C devices have configurable address pins (A0, A1, A2) that must be set to unique values.
Two I2C devices with the same address both acknowledge simultaneously - the master cannot communicate with either one individually. Data reads return corrupted values (logical AND of both devices' responses). In the best case, neither device works. In the worst case, one device works intermittently and the other is completely inaccessible, causing hard-to-diagnose bugs that appear to be firmware issues but are actually hardware address conflicts.
I2C bus address map:
I2C1 Bus (400kHz, pull-ups: 4.7k to 3.3V): BME280 (temp/humidity): 0x76 (SDO pin tied to GND) BMP390 (pressure): 0x77 (SDO pin tied to VCC) AT24C256 EEPROM: 0x50 (A0=A1=A2=GND) INA219 current sensor: 0x40 (A0=GND, A1=GND) All addresses unique - no conflicts. Address pins documented with physical connections on schematic. SPI1 Bus: W25Q128 Flash: nCS = PA4 (dedicated GPIO) Display ILI9341: nCS = PB12 (dedicated GPIO) No shared chip selects.
Address conflict: Two BME280 sensors on same I2C bus. Both have SDO pin tied to GND, giving both address 0x76. Designer intended to read two independent temperature locations but both sensors respond simultaneously. Data reads return 0xFF (both pull bus high = AND of both responses is corrupted). Fix requires: rewiring one SDO to VCC (changes address to 0x77), or using I2C multiplexer (TCA9548A), or moving to separate I2C bus.
KiCad: No built-in I2C address conflict checking. Create a net list and manually tabulate all devices per I2C bus. Add address annotations to schematic.
Altium: Use schematic annotations to document I2C addresses. No automated conflict checking - maintain address map in design documentation.
OrCAD: Add I2C address as component property. Generate report sorted by bus and address to visually identify duplicates.
Bus contention occurs when two or more output drivers attempt to drive the same net to different logic levels simultaneously. This creates a short circuit between VCC and GND through the output transistors of both drivers, causing excessive current (50-200mA per driver), overheating, logic-level violations, and potential permanent damage. Contention must be prevented by design through proper use of tri-state enables, chip selects, and bus arbitration.
Even brief contention during switching transitions (few nanoseconds) causes current spikes that degrade reliability over time.
Sustained bus contention (two drivers actively fighting) can destroy output drivers within seconds from overcurrent heating. Even if not immediately destructive, it creates an undefined voltage level (neither HIGH nor LOW) that causes downstream logic to behave unpredictably - potentially corrupting data, generating false clock edges, or causing state machine lockups. This is particularly dangerous on data buses (SPI MISO, parallel data) where multiple slaves could drive simultaneously.
SPI bus with 3 slaves - no contention:
SPI1_MISO line shared between: - W25Q128 Flash (DO output): Hi-Z when nCS1 = HIGH (verified in datasheet) - ADS1256 ADC (DOUT output): Hi-Z when nCS2 = HIGH (verified in datasheet) - SD Card (DAT0 output): Hi-Z when nCS3 = HIGH (verified) Chip selects are mutually exclusive (only one LOW at a time, controlled by firmware). During idle (all CS HIGH): 10k pull-up on MISO defines bus state as HIGH. During CS transitions: 10ns propagation delay - worst case both Hi-Z briefly (safe). No contention possible.
SPI MISO contention: Three SPI slaves share MISO. But the DAC (MCP4922) does NOT tri-state its SDO pin when CS is high - it continues driving the last output bit. When the MCU selects the Flash (CS_FLASH LOW), both Flash and DAC drive MISO simultaneously. Flash drives HIGH, DAC drives LOW = short circuit. Result: 100mA shoot-through current, MISO voltage = 1.5V (undefined level), data corruption on every Flash read. Both devices slowly degrade from thermal stress.
KiCad: ERC may flag "two outputs on same net" if pin types are correctly defined. Manually verify tri-state behavior for each shared bus device.
Altium: Signal Integrity analysis can detect potential contention. Set pin types correctly for ERC to flag output-output conflicts.
OrCAD: DRC flags output-to-output connections. For tri-state buses, mark pin type as "Tri-state" to allow shared connections without false errors.