<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://stm32world.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Niclas</id>
	<title>Stm32World Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://stm32world.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Niclas"/>
	<link rel="alternate" type="text/html" href="https://stm32world.com/wiki/Special:Contributions/Niclas"/>
	<updated>2026-10-17T00:52:17Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri&amp;diff=8714</id>
		<title>Colibri</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri&amp;diff=8714"/>
		<updated>2026-10-14T05:39:32Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Modules &amp;amp; Carriers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Colibri]][[Category:Work in progress]]{{metadesc|Colibri Automation System}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb tright&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width: 250px;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;width: 250px; height: 150px; overflow: hidden; position: relative; background: #000;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div style=&amp;quot;position: absolute; top: -20px; left: -15px;&amp;quot;&amp;gt;&lt;br /&gt;
        [[File:Colibri_8_photo1.jpg|250px|link=File:Colibri_8_photo1.jpg|alt=Colibri 8 PCB]]&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[File:Colibri-3-6.jpg|thumb|250px]]&lt;br /&gt;
[[File:Colibri_3a_photo1.jpg|thumb|250px]]&lt;br /&gt;
[[File:Colibri rs485u-2.jpg|180px|thumb]]&lt;br /&gt;
[[File:Colibri aic-RevA-2.jpg|180px|thumb]]&lt;br /&gt;
&lt;br /&gt;
Check out the [[Colibri Videos]] on Youtube.&lt;br /&gt;
&lt;br /&gt;
Colibri is a low-cost automation system, primarily intended for building automation, home automation, energy supervision, agriculture supervision and similar systems. Main features beside costs are;&lt;br /&gt;
* Flexible I/O system, via MCU modules, Comm modules and I/O modules in M.2 Key E sockets. Many types already developed.&lt;br /&gt;
* Power supply of 9-36 Volt, either AC or DC (some I/O cards won't work with DC supply, and some not with AC supply)&lt;br /&gt;
* Each I/O slot can be powered-up/down individually from the MCU.&lt;br /&gt;
* Each I/O slot is addressable individually.&lt;br /&gt;
* MCU communicates with each I/O slot via I2C and/or SPI. The I2C bus is multiplexed to avoid address collision. SPI uses one Chip Select per I/O slot and 2 additional Chip Select if multi SPI devices are on a single I/O module.&lt;br /&gt;
* Each I/O module has an 1Mbit EEPROM with calibration parameters and a program for the MCU module to execute. This is accomplished with &amp;quot;PIC&amp;quot; (Position Independent Code) and executing from RAM.&lt;br /&gt;
* Some I/O modules have on-board secondary processors for time-critical or other reasons, for instance RS-485 communication, digital inputs (pulse counting) and PID regulator.&lt;br /&gt;
&lt;br /&gt;
== Architecture Overview ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;res-img&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Colibri_Architecture-1.svg|240px]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Colors in this view represents who creates the software for each part.&lt;br /&gt;
&lt;br /&gt;
== Programming ==&lt;br /&gt;
The Colibri system is designed around two main external projects, [[Colibri Zephyr|Zephyr]] and [http://www.lua.org Lua].&lt;br /&gt;
&lt;br /&gt;
Zephyr provides a lot of ''operating system'' type of features, like task scheduling, concurrency data types, timers, peripheral drivers and cross-platform compatibility to be able to support STM32, RP2354 and possibly other MCU families. &lt;br /&gt;
&lt;br /&gt;
We experimented a bit with WebAssembly, but found the practical barrier a bit too high as well as memory footprint is much more difficult to manage.&lt;br /&gt;
&lt;br /&gt;
Without WebAssembly we are still able to allow for;&lt;br /&gt;
* I/O modules that are unknown to the MCU module to be installed without re-flashing the firmware (using PIC)&lt;br /&gt;
* Uploading of user programs, without flashing the firmware, upload Lua text files&lt;br /&gt;
* Sandboxed execution to limit issues that user programs can create,&lt;br /&gt;
* Simplified tool chain,&lt;br /&gt;
&lt;br /&gt;
The WebAssembly approach might be revisited in the future.&lt;br /&gt;
&lt;br /&gt;
== Carrier Boards ==&lt;br /&gt;
* ''Colibri 3a'' has 2 I/O slots and one MCU slot, one USB-C port to the MCU slot, Jolt Connect pin header for programming. (Postponed to be re-evaluated)&lt;br /&gt;
* ''Colibri 8'' has 7 I/O slots, a Communcation slot, MCU slot, one USB-C port to the MCU slot, Jolt Connect pin header for programming.&lt;br /&gt;
* Planned; ''Colibri 8pi'' is like the ''Colibri 8'' but with a full-fledged Raspberry Pi Compute Module 5. 1 Colibri MCU slot, Comm slot and 7 I/O slots,&lt;br /&gt;
* Planned; ''Colibri 16pi'' is like the ''Colibri 8pi'', but with 15 I/O slots rather than 7.&lt;br /&gt;
&lt;br /&gt;
== MCU Modules ==&lt;br /&gt;
There is a choice, and more will follow;&lt;br /&gt;
&lt;br /&gt;
* ''[[Colibri MCU1]]'' - (deprecated) MCU module with a STM32WLE5, 256kB Flash, 64kB RAM, on-chip LoRa and LoraWAN protocol available in STM32CubeMX.&lt;br /&gt;
* ''[[Colibri MCU2]]'' - MCU module with a STM32H562RG, 1024kB Flash, 640kB RAM and a 16MB external flash memory.&lt;br /&gt;
* ''[[Colibri MCU3]]'' - (deprecated) MCU module with a STM32F405RG, 1MB Flash, 192kB+4kB RAM and a 16MB external flash memory.&lt;br /&gt;
* ''[[Colibri MCU4]]'' - (deprecated) MCU module with a STM32L475RG, 1MB Flash, 128kB RAM and a 16MB external flash memory.&lt;br /&gt;
* ''[[Colibri MCU5]]'' - (deprecated) MCU module with a STM32F103RE, 512kB Flash and 64kB RAM. No external flash memory.&lt;br /&gt;
* ''[[Colibri MCU7]]'' - MCU module with a RP2350A, 16MB external Flash and 520kB RAM&lt;br /&gt;
&lt;br /&gt;
== Comm Modules ==&lt;br /&gt;
Comm modules exist to establish a communication link with the device in one of the currently 4 planned types;&lt;br /&gt;
&lt;br /&gt;
* ''[[Colibri Comm Ethernet]]'' - TCP/IP communications, incl Modbus/TCP, MQTT and HTTPS.&lt;br /&gt;
* ''[[Colibri Comm LoraWAN]]'' - LoraWAN, primarily to report sensor data and status.&lt;br /&gt;
* ''[[Colibri Comm RS485]]'' - For RS485-based protocols, primarily Modbus, but potentially BACnet and others.&lt;br /&gt;
* ''[[Colibri Comm WiFi]]'' - Wireless TCP/IP communications, incl Modbus/TCP, MQTT and HTTPS.&lt;br /&gt;
&lt;br /&gt;
== I/O Modules ==&lt;br /&gt;
The Colibri system is based around the M.2 connector and a non-standard bus for I2C and SPI communications. Each I/O module has an [[Colibri_EEPROM_Layout|EEPROM memory]] available to identify which module is present in each I/O slot, links to documentation, calibration parameters, testing results and (up to) 8kB of C code for the MCU module to execute.&lt;br /&gt;
&lt;br /&gt;
== [[Colibri Form Factor|Form Factor]] ==&lt;br /&gt;
&lt;br /&gt;
Both Colibri I/O modules, Comm modules and MCU modules are 22x42mm and has an edge connector called M.2 Key E, '''but it doesn't follow the M.2 specification for Key E'''. The distance between the I/O slots are specified to 23.5mm, theoretically making it possible for multi-slot I/O modules (none are planned).&lt;br /&gt;
&lt;br /&gt;
The Comm module MUST be have a free zone of at least 5mm between its edge and the edge of the next modules on either side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#FF4444&amp;quot;&amp;gt;'''WARNING!!! Do NOT plug Colibri I/O modules nor any MCU module into other equipment. Do NOT plug any M.2 card into a Colibri system, unless that card/board is specifically made for Colibri.'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules &amp;amp; Carriers ==&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Description &lt;br /&gt;
! Status&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri 3a]]''&lt;br /&gt;
| Carrier&lt;br /&gt;
| Minimal Colibri carrier board with 2 I/O slots and one MCU slot. MCU slot is to be populated with any of the MCU variants available.&lt;br /&gt;
| Deprecated, on hold.&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri 8]]''&lt;br /&gt;
| Carrier&lt;br /&gt;
| Colibri carrier board with Colibri MCU slot and 7 Colibri I/O slots. A galvanically isolated RS-485 port connected to the secondary USART of the MCU slot.&lt;br /&gt;
| Early Access&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri-8pi]]''&lt;br /&gt;
| Carrier&lt;br /&gt;
| Colibri carrier board with Raspberry Pi CM5, Colibri MCU slot, 7 Colibri I/O slots, two Ethernet ports, 3 USB ports and SDcard connector.&lt;br /&gt;
| Planned&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri-16pi]]''&lt;br /&gt;
| Carrier&lt;br /&gt;
| Colibri carrier board with Raspberry Pi CM5, Colibri MCU slot, 15 Colibri I/O slots, two Ethernet ports, 3 USB ports and SDcard connector.&lt;br /&gt;
| Planned&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri 1dp]]''&lt;br /&gt;
| Carrier&lt;br /&gt;
| Minimal Colibri Host with a single MCU slot and 0-500Pa air pressure sensor.&lt;br /&gt;
| Prototype - Re-evaluated after introduction of Comm modules.&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri MCU2]]''&lt;br /&gt;
| MCU module&lt;br /&gt;
| MCU module with a STM32H562RG and a 16MB flash memory.&lt;br /&gt;
| Active&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri MCU7]]''&lt;br /&gt;
| MCU module&lt;br /&gt;
| MCU module with a Raspberry Pi RP2354B and a 16MB flash memory.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri Comm Ethernet]]''&lt;br /&gt;
| Comm module&lt;br /&gt;
| TCP/IP communications, incl Modbus/TCP, MQTT and HTTPS.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri Comm LoraWAN]]''&lt;br /&gt;
| Comm module&lt;br /&gt;
| LoraWAN, primarily to report sensor data and status.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri Comm RS485]]''&lt;br /&gt;
| Comm module&lt;br /&gt;
| For RS485-based protocols, primarily Modbus, but potentially BACnet and others.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri Comm WiFi]]''&lt;br /&gt;
| Comm module&lt;br /&gt;
| Wireless TCP/IP communications, incl Modbus/TCP, MQTT and HTTPS.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[M.2 E Breakout]]''&lt;br /&gt;
| M.2 breakout board&lt;br /&gt;
| Generic breakout board for M.2 E key boards.&lt;br /&gt;
| Active&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri AIC]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Two analog 0-20mA inputs&lt;br /&gt;
| Active&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri AIV]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Two analog 0-10V inputs&lt;br /&gt;
| Active&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri AQV]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Two analog 0-10V outputs&lt;br /&gt;
| Active&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri DII]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Two ISOLATED digital inputs, for state, counter, pulsewidth measurement. On-board STM32C071 for ability to count very fast pulses and high accuracy PWM measurements.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri DIO1]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| IEC 61131-2 compliant, 4-channels digital inputs and outputs.&lt;br /&gt;
| Active&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri DIU]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Four digital inputs, for state, counter, pulsewidth measurement. On-board STM32C071 for ability to count very fast pulses and high accuracy PWM measurements.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri DP1]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| A 0-500Pa air pressure sensor mounted on I/O module.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri DP2]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| A 0-10kPa air pressure sensor mounted on I/O module.&lt;br /&gt;
| Planned&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri DP3]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| A 0-100kPa air pressure sensor mounted on I/O module.&lt;br /&gt;
| Planned&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri Fallback]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Single SPDT relay&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri FET]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Four digital outputs, FET outputs sinking to GND. Max 1 Amp per channel.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri PID1]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| PID regulator, with a PT1000 input and a 0-10V analog output. On-board STM32C071 for host-independent operation.&lt;br /&gt;
| Prototype&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri Pt100]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| One port for 3-wire or 4-wire Pt100 temperature sensor.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri Pt1000]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Two PT1000 temperature sensor inputs.&lt;br /&gt;
| Prototype&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri RS485I]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Isolated RS-485 port. On-board STM32C071 to implement protocols, such as Modbus RTU.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri RS485U]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Two non-isolated RS-485 ports. On-board STM32C071 implementing Modbus protocol.&lt;br /&gt;
| Designed&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri SSR]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Two Solid State Relays, ON/OFF.&lt;br /&gt;
| Prototype&lt;br /&gt;
|-&lt;br /&gt;
| ''[[Colibri TRIAC1]]''&lt;br /&gt;
| I/O module&lt;br /&gt;
| Four Triac outputs, driving 24V AC.&lt;br /&gt;
| Prototype&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= License =&lt;br /&gt;
All Schematics are licensed with the GPLv3, meaning that you are free to make your own designs or manufacture devices using these. We expect that if you derive new design, that you publish these, preferably on this website.&lt;br /&gt;
&lt;br /&gt;
The software will also be published with GPLv3, when something is workable.&lt;br /&gt;
&lt;br /&gt;
= Resources =&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Relay&amp;diff=8685</id>
		<title>Colibri Relay</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Relay&amp;diff=8685"/>
		<updated>2026-10-06T10:15:15Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Colibri]]{{metadesc|Colibri Relay module}}&lt;br /&gt;
[[File:Colibri_relay-rev_A_top_render.png|thumb]]&lt;br /&gt;
  &lt;br /&gt;
Colibri Relay is an digital output I/O module with one SPDT (single-pole, dual-throw) relay.&lt;br /&gt;
&lt;br /&gt;
=== What about that name? ===&lt;br /&gt;
We have extensively used this in HVAC renovation projects, where the customer wants to keep the previous system in place, as an insurance against we going out of business, something breaks or in case the software goes haywire. So, we connect the valve to pin &amp;quot;b&amp;quot;, the Colibri output signal on pin &amp;quot;a&amp;quot; and the old system's output signal on pin &amp;quot;c&amp;quot;. We can remotely control if we want to swap over to previous system, or if the owners wants to do it, they just turn the Colibri system OFF.&lt;br /&gt;
&lt;br /&gt;
=== I2C Addresses === &lt;br /&gt;
  M24M01  = 0x50-0x51&lt;br /&gt;
  PCA9536 = 0x41&lt;br /&gt;
&lt;br /&gt;
= EEPROM factory layout =&lt;br /&gt;
&lt;br /&gt;
See the [[Colibri EEPROM Layout]] page for the full picture.&lt;br /&gt;
&lt;br /&gt;
== Calibration data in EEPROM ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Test Report ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 4&lt;br /&gt;
| Year * 12 + month&lt;br /&gt;
|-&lt;br /&gt;
| 0x0104&lt;br /&gt;
| 4&lt;br /&gt;
| Date * 24 + hour&lt;br /&gt;
|-&lt;br /&gt;
| 0x0108&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0110&lt;br /&gt;
| 4&lt;br /&gt;
| EEPROM write/read/erase test. 32 cycles. Each cycle is represented in one bit. 0=Success, 1=Fail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Schematics ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;res-img&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Colibri_relay-rev_A-schematics.svg|2400px]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Colibri_relay-rev_A_top_render.png&lt;br /&gt;
File:Colibri_relay-rev_A_bot_render.png&lt;br /&gt;
File:Colibri_relay-rev_A_top_right_render.png&lt;br /&gt;
File:Colibri_relay-rev_A_top_left_render.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Fallback&amp;diff=8684</id>
		<title>Colibri Fallback</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Fallback&amp;diff=8684"/>
		<updated>2026-10-06T10:13:58Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Niclas moved page Colibri Fallback to Colibri Relay: Fallback is a legacy name and too narrow.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Colibri Relay]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Relay&amp;diff=8683</id>
		<title>Colibri Relay</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Relay&amp;diff=8683"/>
		<updated>2026-10-06T10:13:58Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Niclas moved page Colibri Fallback to Colibri Relay: Fallback is a legacy name and too narrow.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Colibri]]{{metadesc|Colibri Fallback module}}&lt;br /&gt;
[[File:Colibri_fallback-rev_A_top_render.png|thumb]]&lt;br /&gt;
  &lt;br /&gt;
Colibri Fallback is an digital output I/O module with one SPDT (single-pole, dual-throw) relay.&lt;br /&gt;
&lt;br /&gt;
=== What about that name? ===&lt;br /&gt;
We have extensively used this in HVAC renovation projects, where the customer wants to keep the previous system in place, as an insurance against we going out of business, something breaks or in case the software goes haywire. So, we connect the valve to pin &amp;quot;b&amp;quot;, the Colibri output signal on pin &amp;quot;a&amp;quot; and the old system's output signal on pin &amp;quot;c&amp;quot;. We can remotely control if we want to swap over to previous system, or if the owners wants to do it, they just turn the Colibri system OFF.&lt;br /&gt;
&lt;br /&gt;
=== I2C Addresses === &lt;br /&gt;
  M24M01  = 0x50-0x51&lt;br /&gt;
  PCA9536 = 0x41&lt;br /&gt;
&lt;br /&gt;
= EEPROM factory layout =&lt;br /&gt;
&lt;br /&gt;
See the [[Colibri EEPROM Layout]] page for the full picture.&lt;br /&gt;
&lt;br /&gt;
== Calibration data in EEPROM ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Test Report ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 4&lt;br /&gt;
| Year * 12 + month&lt;br /&gt;
|-&lt;br /&gt;
| 0x0104&lt;br /&gt;
| 4&lt;br /&gt;
| Date * 24 + hour&lt;br /&gt;
|-&lt;br /&gt;
| 0x0108&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0110&lt;br /&gt;
| 4&lt;br /&gt;
| EEPROM write/read/erase test. 32 cycles. Each cycle is represented in one bit. 0=Success, 1=Fail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Schematics ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;res-img&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Colibri_fallback-rev_A-schematics.svg|2400px]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Colibri_fallback-rev_A_top_render.png&lt;br /&gt;
File:Colibri_fallback-rev_A_bot_render.png&lt;br /&gt;
File:Colibri_fallback-rev_A_top_right_render.png&lt;br /&gt;
File:Colibri_fallback-rev_A_top_left_render.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Tutorial&amp;diff=8682</id>
		<title>Colibri Tutorial</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Tutorial&amp;diff=8682"/>
		<updated>2026-10-06T09:59:24Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Created page with &amp;quot;Category:Work in progress{{metadesc|Colibri Automation System}}  &amp;lt;div class=&amp;quot;thumb tright&amp;quot;&amp;gt;   &amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width: 250px;&amp;quot;&amp;gt;     &amp;lt;div style=&amp;quot;width: 250px;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Work in progress]]{{metadesc|Colibri Automation System}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;thumb tright&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;thumbinner&amp;quot; style=&amp;quot;width: 250px;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;width: 250px; height: 150px; overflow: hidden; position: relative; background: #000;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div style=&amp;quot;position: absolute; top: -20px; left: -15px;&amp;quot;&amp;gt;&lt;br /&gt;
        [[File:Colibri_8_photo1.jpg|250px|link=File:Colibri_8_photo1.jpg|alt=Colibri 8 PCB]]&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[File:Colibri-3-6.jpg|thumb|250px]]&lt;br /&gt;
[[File:Colibri_3a_photo1.jpg|thumb|250px]]&lt;br /&gt;
[[File:Colibri rs485u-2.jpg|180px|thumb]]&lt;br /&gt;
[[File:Colibri aic-RevA-2.jpg|180px|thumb]]&lt;br /&gt;
&lt;br /&gt;
= Tutorial Overview = &lt;br /&gt;
&lt;br /&gt;
* [[Colibri Tutorial - Requirements|Requirements]] - Requirements for Hardware and Software&lt;br /&gt;
* [[Colibri Tutorial - Design|Design]] - Solutions for the Requirements in Hardware and Software&lt;br /&gt;
* [[Colibri Tutorial - Architecture|Architecture]] - Details of Software Architecture&lt;br /&gt;
* [[Colibri Tutorial - Colibri 3b|Colibri 3b carrier board]] - Features and functions of the Colibri 3b carrier board.&lt;br /&gt;
* [[Colibri Tutorial - Colibri MCU2|Colibri MCU2, MCU module with STM32H562 ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri Relay|Colibri Relay, One SPDT relay]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri AQV|Colibri AQV, Two 0-10V analog outputs]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri AIV|Colibri AIV, Two 0-10V analog inputs]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri Comm Ethernet|Colibri Comm Ethernet, Comm module with Ethernet ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri AIC|Colibri AIC, Two 0-20mA analog outputs]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri Pt1000|Colibri Pt1000, Two Pt1000 inputs]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri Comm RS485|Colibri Comm RS485, Comm module with isolated RS485 ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri SSR|Colibri SSR, Two Solid State Relays ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri FET|Colibri FET, Four digital sink outputs]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri 8|Colibri 8 carrier board]] - Features and functions of the Colibri 8 carrier board.&lt;br /&gt;
* [[Colibri Tutorial - Colibri DIO1|Colibri DIO1, Four IEC61131-2 compliant inputs/outputs]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri Comm Lora|Colibri Comm Lora, Comm module with LoraWan ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri DIU|Colibri DIU, Four non-isolated digital inputs]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri DII|Colibri DII, Two isolated digital inputs]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri MCU6|Colibri MCU6, MCU module with STM32H735 ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri PID1|Colibri PID1, PID regulator, Pt1000 to 0-10V output ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri Pt100|Colibri Pt100, One 3-wire or 4-wire Pt100 input]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri Comm Wifi|Colibri Comm Wifi, Comm module with Wifi ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri RS485u|Colibri RS485u, Two non-isolated RS485 transceivers ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri RS485i|Colibri RS485i, One isolated RS485 transceiver ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri DP1|Colibri DP1, 0-500Pa pressure sensor]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri MCU7|Colibri MCU7, MCU module with RP2350 ]] - &lt;br /&gt;
* [[Colibri Tutorial - Colibri Triac1|Colibri Triac1, Four Triac outputs ]] -&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline&amp;diff=8650</id>
		<title>Streamline</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline&amp;diff=8650"/>
		<updated>2026-10-02T06:08:43Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Miscellaneous */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:CurrentMakers]][[Category:Work in progress]]{{metadesc|Streamline Development Boards Home}}&lt;br /&gt;
[[File:Streamline Backplane with 2 blades - top right 3.jpg|300px|thumb|Streamline Backplane with 2 blades - 1 Connect and 1 MCU]]&lt;br /&gt;
This page documents the new [[CurrentMakers]] [[Streamline]] series of [[Green]] development boards.  If you are looking for the previous series, that is document here: [[STM32World Legacy]].&lt;br /&gt;
&lt;br /&gt;
[[Streamline]] boards are available here: [https://currentmakers.com/products/streamline/ Streamline on CurrentMakers]&lt;br /&gt;
&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Rationale ==&lt;br /&gt;
[[File:3 STM32World Modules stacked.jpg|300px|thumb]]&lt;br /&gt;
A number of [[STM32World Legacy]] boards have been developed, and produced, and in general the &amp;quot;system&amp;quot; worked very well.  It did however have one fatal flaw which was the sole cause of it never being considered for more widespread production.  This flaw was the board to board connector.&lt;br /&gt;
&lt;br /&gt;
The original boards used a 2x20 standard pin header on each side giving a result of 80 pins.  In terms of connectivity this was a pretty good solution.  It did however present some issues:&lt;br /&gt;
&lt;br /&gt;
# Cost - the long pin 2x20 connectors are fairly expensive - around $0.80 each - so $1.60 per board.  This may not sound that high but when producing a lot it becomes a serious cost.&lt;br /&gt;
# Manufacturing -  the headers can not be manufactured with traditional SMD technologies but require a manual step or hand soldering.&lt;br /&gt;
# Fragile - when shipping or disconnecting boards it is hard not to bend one or more pins and once bend it becomes extremely difficult to reconnect them.&lt;br /&gt;
&lt;br /&gt;
To get around this flaw a new &amp;quot;connector&amp;quot; was considered and after a long search the best solution was the standard PCI-E X8 connector.&lt;br /&gt;
&lt;br /&gt;
== Videos ==&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|5xQqV7BhYxM}}&lt;br /&gt;
&lt;br /&gt;
Receiving the first prototypes ever:&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|YS1w_8ghCf4}}&lt;br /&gt;
&lt;br /&gt;
== Backplane ==&lt;br /&gt;
&lt;br /&gt;
The overall idea is to base [[StreamLine]] around a passive backplane.  The backplane contains a number of PCI connectors with 2 x 49 pins (98) that is simply connected in a parallel bus.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;res-img&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Sl bp 5 top left.png|1000px]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In each end of the bus all the A and B signals are broken out into regular pin headers.&lt;br /&gt;
&lt;br /&gt;
=== Backplane rendering ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Backplane top render.png&lt;br /&gt;
File:Backplane front render.png&lt;br /&gt;
File:Backplane front left render.png&lt;br /&gt;
File:Sl bp 5 top.png&lt;br /&gt;
File:Sl bp 5 top left.png&lt;br /&gt;
File:Sl bp 5 top right.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules ==&lt;br /&gt;
&lt;br /&gt;
=== [[Backplane]]s === &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
! Image&lt;br /&gt;
! Description&lt;br /&gt;
! Status&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline Backplane 5]]&lt;br /&gt;
| [[File:sl_bp_5_top_left.png|80px]]&lt;br /&gt;
| Basic 5 position backplane&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_backplane_5/ Available]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== [[Blade]]s ===&lt;br /&gt;
&lt;br /&gt;
==== STM32 ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
! Image&lt;br /&gt;
! Description&lt;br /&gt;
! Status&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline Connect]] (ST-Link firmware)&lt;br /&gt;
| [[File:Sl prog top left render.png|80px]]&lt;br /&gt;
| Streamline Programmer &amp;amp; Debugger.  This module is essentially identical to [[Jolt Connect]]&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_connect/ Available]&lt;br /&gt;
|- &lt;br /&gt;
| [[Streamline MCU STM32F407]]&lt;br /&gt;
| [[File:Sl mcu stm32f407 top left render.png|80px]]&lt;br /&gt;
| Streamline MCU board including a [[STM32F407]]&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_mcu_stm32f407/ Available]&lt;br /&gt;
|- &lt;br /&gt;
| [[Streamline MCU STM32H562]]&lt;br /&gt;
| [[File:Sl mcu stm32h562 top left render.png|80px]]&lt;br /&gt;
| Streamline MCU board including a [[STM32H562]]&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_mcu_stm32h562/ Available]&lt;br /&gt;
|- &lt;br /&gt;
| [[Streamline MCU STM32L475]]&lt;br /&gt;
| [[File:Sl mcu stm32l475 top left render.png|80px]]&lt;br /&gt;
| Streamline MCU board including a [[STM32L475]]&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_mcu_stm32l475/ Available]&lt;br /&gt;
|- &lt;br /&gt;
| [[Streamline MCU STM32C551]]&lt;br /&gt;
| [[File:Sl_mcu_stm32c551_top_left_render.png|80px]]&lt;br /&gt;
| Streamline MCU board including a [[STM32C551]]&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_mcu_stm32c551/ Available]&lt;br /&gt;
|- &lt;br /&gt;
| [[Streamline MCU STM32H723]]&lt;br /&gt;
| [[File:Sl_mcu_stm32h723_top_left_render.png|80px]]&lt;br /&gt;
| Streamline MCU board including a STM32H723&lt;br /&gt;
| Prototype&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Other MCU's ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
! Image&lt;br /&gt;
! Description&lt;br /&gt;
! Status&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline Connect]] (DAPlink FIrmware)&lt;br /&gt;
| [[File:Sl prog top left render.png|80px]]&lt;br /&gt;
| Streamline Programmer &amp;amp; Debugger.  This module is essentially identical to [[Jolt Connect]]&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_connect/ Available]&lt;br /&gt;
|- &lt;br /&gt;
| [[Streamline MCU RP2354]]&lt;br /&gt;
| [[File:Sl mcu rp2354 top left render.png|80px]]&lt;br /&gt;
| Streamline MCU board including a [[RP2354]]&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_mcu_rp2354/ Available]&lt;br /&gt;
|- &lt;br /&gt;
| [[Streamline MCU ESP32S6]]&lt;br /&gt;
| [[File:Sl mcu esp32s6 top left render.png|80px]]&lt;br /&gt;
| Streamline MCU board including a [[ESP32S6]]&lt;br /&gt;
| Planned&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Miscellaneous ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
! Image&lt;br /&gt;
! Description&lt;br /&gt;
! Status&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline Neopixel 8x8]]&lt;br /&gt;
| [[File:Sl neopixel 8x8 top left render.png|80px]]&lt;br /&gt;
| Module with an 8x8 matrix of Neopixel WS2812 LEDs&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_neopixel_8x8/ Available]&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline Storage SD]]&lt;br /&gt;
| [[File:Sl storage sd top left render rev A.png|80px]]&lt;br /&gt;
| Module with Micro-SD slot&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_sd/ Available]&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline Storage Flash]]&lt;br /&gt;
| [[File:Sl storage flash top left render.png|80px]]&lt;br /&gt;
| Module with 16 MB Flash storage ([[W25q128]])&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_flash/ Available]&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline Storage EEPROM]]&lt;br /&gt;
| [[File:Sl storage eeprom top left render.png|80px]]&lt;br /&gt;
| Module with 512kB EEPROM storage ([[M24M01]])&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_eeprom/ Available]&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline IO Audio DAC]]&lt;br /&gt;
| [[File:Sl_io_pcm5102_top_left_render.png|80px]]&lt;br /&gt;
| PCM5102 I2S Audio DAC&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_io_audio_dac/ Available]&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline IO CAN]]&lt;br /&gt;
| [[File:Sl_io_can_top_left_render.png|80px]]&lt;br /&gt;
| CAN bus interface&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_io_can/ Available]&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline Ethernet]]&lt;br /&gt;
| [[File:Streamline_ethernet_top_left_render.png|80px]]&lt;br /&gt;
| Ethernet interface for STM32F407&lt;br /&gt;
| [https://currentmakers.com/products/streamline/streamline_ethernet/ Available]&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline SPI-Ethernet]]&lt;br /&gt;
| [[File:Streamline_seth_top_left_render.png|80px]]&lt;br /&gt;
| Ethernet interface via the SPI bus&lt;br /&gt;
| Prototype&lt;br /&gt;
|-&lt;br /&gt;
| [[Streamline RS485]]&lt;br /&gt;
| [[File:Streamline_rs485_top_left_render.png|80px]]&lt;br /&gt;
| Non-isolated RS485 interface&lt;br /&gt;
| Prototype&lt;br /&gt;
|-&lt;br /&gt;
| Streamline Real Time Clock&lt;br /&gt;
| &lt;br /&gt;
| Real time clock with on board coin cell battery (or supercap) backup&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline ESC&lt;br /&gt;
| &lt;br /&gt;
| Electronic speed control for BLDC motors&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline HS USB&lt;br /&gt;
| &lt;br /&gt;
| HS USB blade using [[USB3300]]&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline WiFi&lt;br /&gt;
| &lt;br /&gt;
| WiFi interface&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline Temperature/Humidity&lt;br /&gt;
| &lt;br /&gt;
| Sensor of temperature and humidity&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline Compass&lt;br /&gt;
| &lt;br /&gt;
| Compass&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline Gyro&lt;br /&gt;
| &lt;br /&gt;
| Gyro&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline Accelerometer&lt;br /&gt;
| &lt;br /&gt;
| Accelerometer&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline GPS&lt;br /&gt;
| &lt;br /&gt;
| GPS&lt;br /&gt;
| Idea&lt;br /&gt;
|-&lt;br /&gt;
| Streamline FM Radio&lt;br /&gt;
| &lt;br /&gt;
| FM and DAB radio receiver&lt;br /&gt;
| Idea&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Standard Pinout ==&lt;br /&gt;
&lt;br /&gt;
The pinout table is based on a [[MCU]] board with a 100 pin STM32F407.  Boards using [[STM32]] [[MCU]]s with less pins will leave some of the pins unused.&lt;br /&gt;
&lt;br /&gt;
* [[Streamline Peripheral Pin Mapping]] - peripheral-by-peripheral pin mapping.&lt;br /&gt;
* [[Streamline Header Mapping]] - Backplane-to-GPIO and GPIO-to-Backplane mapping.&lt;br /&gt;
&lt;br /&gt;
== Prototype Photos == &lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Streamline Backplane with 2 blades - top right 3.jpg&lt;br /&gt;
File:Streamline Backplane with 2 blades - top right 2.jpg&lt;br /&gt;
File:Streamline Backplane with 2 blades - top right.jpg&lt;br /&gt;
File:Streamline Backplane with 2 blades - top left.jpg&lt;br /&gt;
File:Streamline Backplane with 2 blades - front.jpg&lt;br /&gt;
File:Streamline Multiple Blades.jpg&lt;br /&gt;
File:Streamline MCU STM32L475 - top view.jpg&lt;br /&gt;
File:Streamline MCU STM32L475 - bottom view.jpg&lt;br /&gt;
File:Streamline MCU STM32H562 - top view.jpg&lt;br /&gt;
File:Streamline MCU STM32H562 - bottom view.jpg&lt;br /&gt;
File:Streamline MCU STM32F407 - top view.jpg&lt;br /&gt;
File:Streamline MCU STM32F407 - bottom view.jpg&lt;br /&gt;
File:Streamline Connect - top view.jpg&lt;br /&gt;
File:Streamline Connect - bottom view.jpg&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://currentmakers.com CurrentMakers main site]&lt;br /&gt;
* [https://github.com/currentmakers/streamline_kicad_libraries Streamline KiCAD Libraries]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8602</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8602"/>
		<updated>2026-09-26T07:42:33Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* SWD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== LED &amp;amp; Button ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|LED&lt;br /&gt;
| PC13&lt;br /&gt;
| PC13&lt;br /&gt;
| PC13&lt;br /&gt;
| PC13&lt;br /&gt;
| PC13&lt;br /&gt;
| PC13&lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|Button&lt;br /&gt;
| PC15&lt;br /&gt;
| PC15&lt;br /&gt;
| PC15&lt;br /&gt;
| PC15&lt;br /&gt;
| PC15&lt;br /&gt;
| PC15&lt;br /&gt;
| GPIO47&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| GPIO6&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| GPIO7&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
| rowspan=2 | Conflict with USB&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8582</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8582"/>
		<updated>2026-09-23T08:34:04Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Macros, Pragmas &amp;amp; Preprocessor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exit since there is nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;, and for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; types it can also be &amp;lt;code&amp;gt;unsigned&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will also allow various emissions and stacking.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
short i = 10;&lt;br /&gt;
long i = 10;&lt;br /&gt;
unsigned short i = 10;&lt;br /&gt;
unsigned long long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Type Casting ===&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax. One reason it is quite easy to end up with the worst spaghetti code possible, as the compiler will not guard against structural mismatching.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
=== Pointer Arithmetic ===&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Common Compile Errors ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8581</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8581"/>
		<updated>2026-09-23T08:33:09Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Expressions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exit since there is nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;, and for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; types it can also be &amp;lt;code&amp;gt;unsigned&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will also allow various emissions and stacking.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
short i = 10;&lt;br /&gt;
long i = 10;&lt;br /&gt;
unsigned short i = 10;&lt;br /&gt;
unsigned long long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Type Casting ===&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax. One reason it is quite easy to end up with the worst spaghetti code possible, as the compiler will not guard against structural mismatching.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
=== Pointer Arithmetic ===&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8580</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8580"/>
		<updated>2026-09-23T08:28:46Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exit since there is nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;, and for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; types it can also be &amp;lt;code&amp;gt;unsigned&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will also allow various emissions and stacking.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
short i = 10;&lt;br /&gt;
long i = 10;&lt;br /&gt;
unsigned short i = 10;&lt;br /&gt;
unsigned long long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Type Casting ===&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax. One reason it is quite easy to end up with the worst spaghetti code possible, as the compiler will not guard against structural mismatching.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
=== Pointer Arithmetic ===&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8579</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8579"/>
		<updated>2026-09-23T08:23:26Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Variable types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exit since there is nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;, and for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; types it can also be &amp;lt;code&amp;gt;unsigned&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will also allow various emissions and stacking.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
short i = 10;&lt;br /&gt;
long i = 10;&lt;br /&gt;
unsigned short i = 10;&lt;br /&gt;
unsigned long long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8578</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8578"/>
		<updated>2026-09-23T08:21:11Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Variable types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exit since there is nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;, and for &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; types it can also be &amp;lt;code&amp;gt;unsigned&amp;lt;/code&amp;gt;. The compiler will also allow various emissions, such as &amp;lt;code&amp;gt;long my_variable;&amp;lt;/code&amp;gt;, and stacking such as &amp;lt;code&amp;gt;unsigned long long my_variable;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8577</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8577"/>
		<updated>2026-09-23T08:16:59Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Loops &amp;amp; Iteration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exit since there is nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8576</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8576"/>
		<updated>2026-09-23T08:16:46Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Loops &amp;amp; Iteration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exit since there is nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
while (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8575</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8575"/>
		<updated>2026-09-23T08:16:17Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Embedded */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exit since there is nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8574</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8574"/>
		<updated>2026-09-23T08:14:03Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Embedded */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop (called the &amp;quot;super loop&amp;quot; or &amp;quot;main loop&amp;quot;), or hand over control to an operating system that doesn't return.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8573</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8573"/>
		<updated>2026-09-23T08:12:12Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Embedded */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exit, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8572</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8572"/>
		<updated>2026-09-23T08:06:07Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Expressions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exist, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
=== Operators ===&lt;br /&gt;
&lt;br /&gt;
=== Order of Evaluation ===&lt;br /&gt;
&lt;br /&gt;
=== Precedence ===&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8571</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8571"/>
		<updated>2026-09-23T08:05:16Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Control Flow &amp;amp; Decision Making */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exist, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Expressions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8570</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8570"/>
		<updated>2026-09-23T08:04:31Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Standard UNIX */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. The convention is that returning a non-zero value indicates an error.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exist, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8569</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8569"/>
		<updated>2026-09-23T08:03:46Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Standard UNIX */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;int argc&amp;lt;/code&amp;gt; is a variable containing how many command-line arguments was received, and &amp;lt;code&amp;gt;char** argv&amp;lt;/code&amp;gt; is an array (think of a list) with those arguments). The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exist, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8568</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8568"/>
		<updated>2026-09-23T07:59:19Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Standard UNIX */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions interacting with the I/O system in the operating system, such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; explain that the function does not need any input arguments. The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exist, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8567</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8567"/>
		<updated>2026-09-23T07:58:41Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Standard UNIX */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint (called &amp;quot;function prototype&amp;quot;) for functions such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; explain that the function does not need any input arguments. The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exist, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8566</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8566"/>
		<updated>2026-09-23T07:56:39Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint for functions such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; explain that the function does not need any input arguments. The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exist, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Running the same on a Debian 64-bit OS,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 8&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 16&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the difference of sizes of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; and others, but the same sizes of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; and so forth.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8565</id>
		<title>Learning C</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Learning_C&amp;diff=8565"/>
		<updated>2026-09-23T07:50:01Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Fixed width types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:C]][[Category:Work in progress]]{{metadesc|Learning C tutorial}}&lt;br /&gt;
[[File:c-programming-language-1.jpg|thumb|300px|Cover of the 2nd edition of &amp;quot;The C Programming Language&amp;quot;]]&lt;br /&gt;
[[C]] is a general purpose programming language which was created in 1972 by Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
While it was originally designed to implement operating systems, the features which made the language ideal for that purpose, also make it ideal for developing software for small resource constrained [[MCU]]s.&lt;br /&gt;
&lt;br /&gt;
On this page we will go through how to use C for embedded development.&lt;br /&gt;
{{clear}}&lt;br /&gt;
== Hello World - Desktop vs. MCU ==&lt;br /&gt;
&lt;br /&gt;
When learning any programming language, the first &amp;quot;project&amp;quot; will typically be a small program which prints out &amp;quot;Hello World!&amp;quot;.  C was designed to give programmers relatively direct access to the target hardware.  This was ideal for creating operating systems and indeed most, if not all, serious operating systems are largely implemented in C.  This design also make [[C]] an ideal language for developing embedded software targeting small [[MCU]]s with very limited resources.&lt;br /&gt;
&lt;br /&gt;
=== Standard UNIX ===&lt;br /&gt;
&lt;br /&gt;
On a standard UNIX system, that program, implemented in standard C, would typically look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
    printf(&amp;quot;Hello World!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us break down the classic C program line by line.&lt;br /&gt;
&lt;br /&gt;
Line 1 contains a '''Preprocessor Directive'''.  This essentially instruct the compiler to include a header file called &amp;lt;code&amp;gt;stdio.h&amp;lt;/code&amp;gt; (Standard Input/Output).  This file in turn contains the blueprint for functions such as &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In line 3 follows a function declaration, creating a function named &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.  Every C program includes a function called &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; and this function serves as the entry point.  The &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; tell the compiler that this function will return an integer value and the &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; explain that the function does not need any input arguments. The actual function code is enclosed in a code block using curly brackets.&lt;br /&gt;
&lt;br /&gt;
In line 4 we call the function &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; which will print a string on the terminal executing the program.  The &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; is provided with an argument, which is a string enclosed in double-quotes &amp;lt;code&amp;gt;&amp;quot;Hello World!&amp;quot;&amp;lt;/code&amp;gt;.  The compiler will include this string as a constant.&lt;br /&gt;
&lt;br /&gt;
Finally in line 5, we return the value &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Most UNIX like systems have (or bloody should have) a C compiler, typically named &amp;lt;code&amp;gt;cc&amp;lt;/code&amp;gt;, so above &amp;lt;code&amp;gt;hello.c&amp;lt;/code&amp;gt; can be built into a binary executable thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce a binary ''hello'', which can now be executed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./hello&lt;br /&gt;
Hello World!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded ===&lt;br /&gt;
&lt;br /&gt;
On an embedded system using any [[MCU]] whether it be [[STM32]], [[RP2350]] or any other, things get a little bit more complicated.  On a [[UNIX]] system, the kernel knows how to execute a binary, and the shell (for example Bash) know how to load it, pass parameters and interpret the return value.  Typically, a [[MCU]] core will simply jump to a specific address - often &amp;lt;code&amp;gt;0x00000000&amp;lt;/code&amp;gt;.  The actual format of the binary depends on the [[MCU]] core in use and the architecture.  There are seldom a general way to print information, so typically the developer will need to specify how to print.  Finally, an embedded application will never actually exist, so the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; will typically run an infinite loop called the &amp;quot;super loop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
During boot, typically, part of the [[MCU]] will need to be initialized.  It ''is'' possible to do this manually, but it will often be handled by some sdk provided by the vendor of the [[MCU]].  This startup code will typically lead up to calling &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Skipping the actual [[MCU]] initialization and only blinking a [[LED]] rather than printing a statement, a very minimal &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; could look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    uint16_t led = PIN('C', 13);           // Blue LED&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= BIT(PINBANK(led));     // Enable GPIO clock for LED&lt;br /&gt;
    gpio_set_mode(led, GPIO_MODE_OUTPUT);  // Set blue LED to output mode&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        gpio_write(led, true);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
        gpio_write(led, false);&lt;br /&gt;
        spin(999999);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will all appear quite incomprehensible for a C beginner, but for now let's just realize that a C program always have a &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function and on embedded systems this function will normally never exist since it's got nowhere else to go.&lt;br /&gt;
&lt;br /&gt;
== Variables &amp;amp; Fixed-Width Types ==&lt;br /&gt;
&lt;br /&gt;
Variables is one of the key concepts in (almost) any programming language.  A variable is a named container which can contain any value of the type of the variable.&lt;br /&gt;
&lt;br /&gt;
=== Variable declaration ===&lt;br /&gt;
&lt;br /&gt;
The most basic variable declaration in [[C]] looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code snippet will declare (create) a variable by the name &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; with a '''type''' of &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; and assigning an initial value of &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The type &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; is an integer.  The actual number of bits in an int depends on the platform but on a 32 bit [[MCU]] it is most often 32 bits.  The value is signed, so it can hold values in the following range:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-2,147,483,648 to 2,147,483,647 (2^31 − 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable types ===&lt;br /&gt;
&lt;br /&gt;
[[C]] only defines a few basic types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type&lt;br /&gt;
! Range&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| char &lt;br /&gt;
| 0 - 255&lt;br /&gt;
| A single byte capable of holding one character &lt;br /&gt;
|- &lt;br /&gt;
| int&lt;br /&gt;
| -2,147,483,648 - 2,147,483,647&lt;br /&gt;
| An integer - on modern 32-bit [[MCU]]s typically a 32-bit value&lt;br /&gt;
|-&lt;br /&gt;
| float&lt;br /&gt;
| ±1.175 × 10⁻³⁸ to ±3.403 × 10³⁸&lt;br /&gt;
| 32-bit floating point value&lt;br /&gt;
|-&lt;br /&gt;
| double&lt;br /&gt;
| ±1.7 × 10^308&lt;br /&gt;
| 64-bit (8 byte) floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The types can be modified by applying a so-called ''modifier'', which can be either &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
long int i = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fixed width types ====&lt;br /&gt;
&lt;br /&gt;
In K&amp;amp;R, the following is mentioned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Each compiler is free to choose appropriate sizes for its own hardware, subject only &lt;br /&gt;
to the the restriction that shorts and ints are at least 16 bits, longs are&lt;br /&gt;
at least 32 bits, and short is no longer than int, which is no longer than long&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This unpredictable nature can be troublesome when creating libraries that need to work on multiple platforms, or used for protocol and data format implementations.  For that reason, a library called &amp;lt;code&amp;gt;[https://en.cppreference.com/c/header/stdint stdint.h]&amp;lt;/code&amp;gt; was added in C99 containing: &amp;lt;code&amp;gt;uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t&amp;lt;/code&amp;gt; for unsigned and signed integer types of specific number of bits.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Consider the following code running on a [[STM32]] [[MCU]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
    printf(&amp;quot;\n\n\n--------\nStarting\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;sizeof(char) = %d\n&amp;quot;, sizeof(char));&lt;br /&gt;
    printf(&amp;quot;sizeof(short int) = %d\n&amp;quot;, sizeof(short int));&lt;br /&gt;
    printf(&amp;quot;sizeof(int) = %d\n&amp;quot;, sizeof(int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long int) = %d\n&amp;quot;, sizeof(long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(long long int) = %d\n&amp;quot;, sizeof(long long int));&lt;br /&gt;
    printf(&amp;quot;sizeof(float) = %d\n&amp;quot;, sizeof(float));&lt;br /&gt;
    printf(&amp;quot;sizeof(double) = %d\n&amp;quot;, sizeof(double));&lt;br /&gt;
    printf(&amp;quot;sizeof(long double) = %d\n&amp;quot;, sizeof(long double));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint8_t) = %d\n&amp;quot;, sizeof(uint8_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint16_t) = %d\n&amp;quot;, sizeof(uint16_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint32_t) = %d\n&amp;quot;, sizeof(uint32_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(uint64_t) = %d\n&amp;quot;, sizeof(uint64_t));&lt;br /&gt;
    printf(&amp;quot;sizeof(void *) = %d\n&amp;quot;, sizeof(void*));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------&lt;br /&gt;
Starting&lt;br /&gt;
sizeof(char) = 1&lt;br /&gt;
sizeof(short int) = 2&lt;br /&gt;
sizeof(int) = 4&lt;br /&gt;
sizeof(long int) = 4&lt;br /&gt;
sizeof(long long int) = 8&lt;br /&gt;
sizeof(float) = 4&lt;br /&gt;
sizeof(double) = 8&lt;br /&gt;
sizeof(long double) = 8&lt;br /&gt;
sizeof(uint8_t) = 1&lt;br /&gt;
sizeof(uint16_t) = 2&lt;br /&gt;
sizeof(uint32_t) = 4&lt;br /&gt;
sizeof(uint64_t) = 8&lt;br /&gt;
sizeof(void *) = 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
Variables in [[C]] can be declared in different locations (scopes). If a variable is declared before any function declarations they are said to be ''global'', but a variable can also be declared inside a function which will limit the scope to that particular functions.  For this reason, local variables can have the same name and each will refer to the local value.&lt;br /&gt;
&lt;br /&gt;
== Control Flow &amp;amp; Decision Making ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Loops &amp;amp; Iteration ==&lt;br /&gt;
&lt;br /&gt;
=== The Super Loop ===&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, embedded programs are never supposed to exit, since they got nowhere to go really.  They often achieve this by running an endless loop, known as the super loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (1) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The endless loop ''can'' be written in multiple ways.  Another often seen approach is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
for (;;) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which one is the most efficient is a topic of an almost religious discussion.  There might have been a time where one was better than the other (better as in wasting less cpu cycles) but with modern optimizing compilers I doubt very much that there will be any difference.&lt;br /&gt;
&lt;br /&gt;
Fans of &amp;quot;The Hitchhikers Guide to the Galaxy&amp;quot; will appreciate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
While (42) { // Loop forever&lt;br /&gt;
    // Do something here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will execute exactly like the first one, taking advantage of the fact that anything non-zero is &amp;quot;true&amp;quot; per definition.&lt;br /&gt;
&lt;br /&gt;
For the final approach we'll look at a feature seldom used in [[C]] programs.  K&amp;amp;R describes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto&lt;br /&gt;
statement is never necessary, and in practice it is almost always easy to write code without it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apart from being hilarious it does open the possibility of doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
loop_start:&lt;br /&gt;
//Do something&lt;br /&gt;
goto loop_start;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While I have ''never'' seen this in the wild, it is technically valid [[C]] syntax.&lt;br /&gt;
&lt;br /&gt;
== Functions &amp;amp; Modular Code == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Bitwise Operations Masterclass == &lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Pointers Demystified ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Arrays &amp;amp; Pointer Arithmetic ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Structs &amp;amp; Memory Alignment ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== The volatile Keyword ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Type Casting &amp;amp; Unions ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Function Pointers &amp;amp; Callbacks ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Enums &amp;amp; State Machines ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Dynamic Memory vs. Static Allocation ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Macros, Pragmas &amp;amp; Preprocessor ==&lt;br /&gt;
&lt;br /&gt;
To be added&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links == &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span class=&amp;quot;newwin&amp;quot;&amp;gt;[[Media:The C Programming Language (Kernighan Ritchie).pdf|Kernighan &amp;amp; Ritchie: The C Programming Language (2nd Edition)]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_MCU_STM32H723&amp;diff=8512</id>
		<title>Streamline MCU STM32H723</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_MCU_STM32H723&amp;diff=8512"/>
		<updated>2026-09-17T13:05:41Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Blade]]{{metadesc|STM32H723 Streamline MCU board documentation}}&lt;br /&gt;
[[File:sl_mcu_stm32h723-rev_A_top_right_render.png|350px|thumb|Streamline MCU STM32H723]]&lt;br /&gt;
The [[Streamline MCU STM32H723]] is a higher performant [[Streamline]] [[STM32]] [[MCU]] board build around a [[STM32H723]].&lt;br /&gt;
{{clear}}&lt;br /&gt;
&lt;br /&gt;
== Specifications ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
|'''MCU'''&lt;br /&gt;
|STM32H723VE&lt;br /&gt;
|-&lt;br /&gt;
|'''Flash'''&lt;br /&gt;
|512kB&lt;br /&gt;
|-&lt;br /&gt;
|'''RAM'''&lt;br /&gt;
|564kB&lt;br /&gt;
|-&lt;br /&gt;
|'''Crystal'''&lt;br /&gt;
|16MHz&lt;br /&gt;
|-&lt;br /&gt;
|'''LED'''&lt;br /&gt;
|PC13 (open drain)&lt;br /&gt;
|-&lt;br /&gt;
|'''Button'''&lt;br /&gt;
|Boot0/PA14 (pulled down)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Schematics ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;res-img&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Sl mcu stm32h723.svg|2400px]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_top_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_top_right_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_top_left_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_bot_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_bot_right_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_bot_left_render.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.st.com/resource/en/datasheet/stm32h723ve.pdf Datasheet]&lt;br /&gt;
* [https://www.st.com/resource/en/reference_manual/rm0468-stm32h723733-stm32h725735-and-stm32h730-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf STM32H723/725/730/733/735 Reference Manual]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_MCU_STM32H723&amp;diff=8511</id>
		<title>Streamline MCU STM32H723</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_MCU_STM32H723&amp;diff=8511"/>
		<updated>2026-09-17T13:05:21Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Blade]]{{metadesc|STM32H723 Streamline MCU board documentation}}&lt;br /&gt;
[[File:sl_mcu_stm32h723-rev_A_top_right_render.png|350px|thumb|Streamline MCU STM32H723]]&lt;br /&gt;
The [[Streamline MCU STM32H723]] is a higher performant [[Streamline]] [[STM32]] [[MCU]] board build around a [[STM32H723]].&lt;br /&gt;
{{clear}}&lt;br /&gt;
&lt;br /&gt;
== Specifications ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
|'''MCU'''&lt;br /&gt;
|STM32H723VE&lt;br /&gt;
|-&lt;br /&gt;
|'''Flash'''&lt;br /&gt;
|512kB&lt;br /&gt;
|-&lt;br /&gt;
|'''RAM'''&lt;br /&gt;
|564kB&lt;br /&gt;
|-&lt;br /&gt;
|'''Crystal'''&lt;br /&gt;
|16MHz&lt;br /&gt;
|-&lt;br /&gt;
|'''LED'''&lt;br /&gt;
|PC13 (open drain)&lt;br /&gt;
|-&lt;br /&gt;
|'''Button'''&lt;br /&gt;
|Boot0/PC15 (pulled down)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Schematics ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;res-img&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Sl mcu stm32h723.svg|2400px]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_top_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_top_right_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_top_left_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_bot_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_bot_right_render.png&lt;br /&gt;
File:sl_mcu_stm32h723-rev_A_bot_left_render.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.st.com/resource/en/datasheet/stm32h723ve.pdf Datasheet]&lt;br /&gt;
* [https://www.st.com/resource/en/reference_manual/rm0468-stm32h723733-stm32h725735-and-stm32h730-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf STM32H723/725/730/733/735 Reference Manual]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354_bot_render.png&amp;diff=8510</id>
		<title>File:Sl mcu rp2354 bot render.png</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354_bot_render.png&amp;diff=8510"/>
		<updated>2026-09-17T13:01:07Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Niclas uploaded a new version of File:Sl mcu rp2354 bot render.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;File uploaded with MsUpload&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354_top_left_render.png&amp;diff=8509</id>
		<title>File:Sl mcu rp2354 top left render.png</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354_top_left_render.png&amp;diff=8509"/>
		<updated>2026-09-17T13:00:33Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Niclas uploaded a new version of File:Sl mcu rp2354 top left render.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;File uploaded with MsUpload&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354_top_render.png&amp;diff=8508</id>
		<title>File:Sl mcu rp2354 top render.png</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354_top_render.png&amp;diff=8508"/>
		<updated>2026-09-17T13:00:06Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Niclas uploaded a new version of File:Sl mcu rp2354 top render.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;File uploaded with MsUpload&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354_top_right_render.png&amp;diff=8507</id>
		<title>File:Sl mcu rp2354 top right render.png</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354_top_right_render.png&amp;diff=8507"/>
		<updated>2026-09-17T12:59:34Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Niclas uploaded a new version of File:Sl mcu rp2354 top right render.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;File uploaded with MsUpload&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354.svg&amp;diff=8506</id>
		<title>File:Sl mcu rp2354.svg</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=File:Sl_mcu_rp2354.svg&amp;diff=8506"/>
		<updated>2026-09-17T12:58:16Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Niclas uploaded a new version of File:Sl mcu rp2354.svg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;File uploaded with MsUpload&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=File:Streamline_seth.svg&amp;diff=8505</id>
		<title>File:Streamline seth.svg</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=File:Streamline_seth.svg&amp;diff=8505"/>
		<updated>2026-09-17T12:51:12Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Niclas uploaded a new version of File:Streamline seth.svg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8501</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8501"/>
		<updated>2026-09-11T15:49:33Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* CAN */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| GPIO6&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| GPIO7&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
| rowspan=2 | Conflict with USB&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8500</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8500"/>
		<updated>2026-09-11T15:43:03Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* SPI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| GPIO6&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| GPIO7&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8499</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8499"/>
		<updated>2026-09-11T15:42:54Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* I2C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| GPIO6&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| GPIO7&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI0 SCK: 2 / 6 / 18 / 22 / 34 / 38 &lt;br /&gt;
* RP2350 SPI0 MISO: 0 / 4 / 16 / 20 / 32 / 36&lt;br /&gt;
* RP2350 SPI0 MOSI: 3 / 7 / 19 / 23 / 35 / 39&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI1 SCK: 10 / 14 / 26 / 30 / 42 / 46&lt;br /&gt;
* RP2350 SPI1 MISO: 8 / 12 / 24 / 28 / 40 / 44&lt;br /&gt;
* RP2350 SPI1 MOSI: 11 / 15 / 27 / 31 / 43 / 47&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8498</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8498"/>
		<updated>2026-09-11T15:42:38Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* UARTs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| GPIO6&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| GPIO7&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C0 SCL: 1 / 5 / 9 / 13 / 17 / 21 / 25 / 29 / 33 / 37 / 41 / 45&lt;br /&gt;
* RP2350 I2C0 SDA: 0 / 4 / 8 / 12 / 16 / 20 / 24 / 28 / 32 / 36 / 40 / 44&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C1 SCL: 3 / 7 / 11 / 15 / 19 / 23 / 27 / 31 / 35 / 39 / 43 / 47&lt;br /&gt;
* RP2350 I2C1 SDA: 2 / 6 / 10 / 14 / 18 / 22 / 26 / 30 / 34 / 38 / 42 / 46&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI0 SCK: 2 / 6 / 18 / 22 / 34 / 38 &lt;br /&gt;
* RP2350 SPI0 MISO: 0 / 4 / 16 / 20 / 32 / 36&lt;br /&gt;
* RP2350 SPI0 MOSI: 3 / 7 / 19 / 23 / 35 / 39&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI1 SCK: 10 / 14 / 26 / 30 / 42 / 46&lt;br /&gt;
* RP2350 SPI1 MISO: 8 / 12 / 24 / 28 / 40 / 44&lt;br /&gt;
* RP2350 SPI1 MOSI: 11 / 15 / 27 / 31 / 43 / 47&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8497</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8497"/>
		<updated>2026-09-11T15:42:13Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* UARTs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 UART0 TX:  0 / 12 / 16 / 28 / 32 / 44&lt;br /&gt;
* RP2350 UART0 RX:  1 / 13 / 17 / 29 / 33 / 45&lt;br /&gt;
&lt;br /&gt;
* RP2350 UART1 TX: 4 / 8 / 20 / 24 / 36 / 40&lt;br /&gt;
* RP2350 UART1 RX: 5 / 9 / 21 / 25 / 37 / 41&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| GPIO6&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| GPIO7&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C0 SCL: 1 / 5 / 9 / 13 / 17 / 21 / 25 / 29 / 33 / 37 / 41 / 45&lt;br /&gt;
* RP2350 I2C0 SDA: 0 / 4 / 8 / 12 / 16 / 20 / 24 / 28 / 32 / 36 / 40 / 44&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C1 SCL: 3 / 7 / 11 / 15 / 19 / 23 / 27 / 31 / 35 / 39 / 43 / 47&lt;br /&gt;
* RP2350 I2C1 SDA: 2 / 6 / 10 / 14 / 18 / 22 / 26 / 30 / 34 / 38 / 42 / 46&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI0 SCK: 2 / 6 / 18 / 22 / 34 / 38 &lt;br /&gt;
* RP2350 SPI0 MISO: 0 / 4 / 16 / 20 / 32 / 36&lt;br /&gt;
* RP2350 SPI0 MOSI: 3 / 7 / 19 / 23 / 35 / 39&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI1 SCK: 10 / 14 / 26 / 30 / 42 / 46&lt;br /&gt;
* RP2350 SPI1 MISO: 8 / 12 / 24 / 28 / 40 / 44&lt;br /&gt;
* RP2350 SPI1 MOSI: 11 / 15 / 27 / 31 / 43 / 47&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8496</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8496"/>
		<updated>2026-09-11T15:41:45Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
'''WIP: I2Sx_ for STM32 has not been entered yet.'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30: SDIO_CMD&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31: SDIO_CK&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32: SDIO_D3&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33: SDIO_D2&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| GPIO6: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| GPIO7: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35: SDIO_D0&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34: SDIO_D1&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8495</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8495"/>
		<updated>2026-09-11T15:35:39Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
'''WIP: I2Sx_ for STM32 has not been entered yet.'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30: SDIO_CMD&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31: SDIO_CK&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32: SDIO_D3&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33: SDIO_D2&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35: SDIO_D0&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34: SDIO_D1&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8494</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8494"/>
		<updated>2026-09-11T15:35:00Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
WIP: __I2Sx for STM32 has not been entered yet.__&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30: SDIO_CMD&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31: SDIO_CK&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32: SDIO_D3&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33: SDIO_D2&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35: SDIO_D0&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34: SDIO_D1&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8493</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8493"/>
		<updated>2026-09-11T15:34:46Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
WIP: ___I2Sx_ for STM32 has not been entered yet.___&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30: SDIO_CMD&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31: SDIO_CK&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32: SDIO_D3&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33: SDIO_D2&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35: SDIO_D0&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34: SDIO_D1&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8492</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8492"/>
		<updated>2026-09-11T15:34:32Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
WIP: **I2Sx_ for STM32 has not been entered yet.**&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30: SDIO_CMD&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31: SDIO_CK&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32: SDIO_D3&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33: SDIO_D2&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35: SDIO_D0&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34: SDIO_D1&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8491</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8491"/>
		<updated>2026-09-11T15:34:18Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
**WIP: I2Sx_ for STM32 has not been entered yet.**&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30: SDIO_CMD&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31: SDIO_CK&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32: SDIO_D3&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33: SDIO_D2&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35: SDIO_D0&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34: SDIO_D1&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8490</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8490"/>
		<updated>2026-09-11T15:34:08Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
***WIP: I2Sx_ for STM32 has not been entered yet.***&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30: SDIO_CMD&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31: SDIO_CK&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32: SDIO_D3&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33: SDIO_D2&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35: SDIO_D0&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34: SDIO_D1&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8489</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8489"/>
		<updated>2026-09-11T15:32:24Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30: SDIO_CMD&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31: SDIO_CK&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32: SDIO_D3&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33: SDIO_D2&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35: SDIO_D0&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34: SDIO_D1&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8488</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8488"/>
		<updated>2026-09-11T15:29:26Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* I2S */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 UART0 TX:  0 / 12 / 16 / 28 / 32 / 44&lt;br /&gt;
* RP2350 UART0 RX:  1 / 13 / 17 / 29 / 33 / 45&lt;br /&gt;
&lt;br /&gt;
* RP2350 UART1 TX: 4 / 8 / 20 / 24 / 36 / 40&lt;br /&gt;
* RP2350 UART1 RX: 5 / 9 / 21 / 25 / 37 / 41&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C0 SCL: 1 / 5 / 9 / 13 / 17 / 21 / 25 / 29 / 33 / 37 / 41 / 45&lt;br /&gt;
* RP2350 I2C0 SDA: 0 / 4 / 8 / 12 / 16 / 20 / 24 / 28 / 32 / 36 / 40 / 44&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C1 SCL: 3 / 7 / 11 / 15 / 19 / 23 / 27 / 31 / 35 / 39 / 43 / 47&lt;br /&gt;
* RP2350 I2C1 SDA: 2 / 6 / 10 / 14 / 18 / 22 / 26 / 30 / 34 / 38 / 42 / 46&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI0 SCK: 2 / 6 / 18 / 22 / 34 / 38 &lt;br /&gt;
* RP2350 SPI0 MISO: 0 / 4 / 16 / 20 / 32 / 36&lt;br /&gt;
* RP2350 SPI0 MOSI: 3 / 7 / 19 / 23 / 35 / 39&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI1 SCK: 10 / 14 / 26 / 30 / 42 / 46&lt;br /&gt;
* RP2350 SPI1 MISO: 8 / 12 / 24 / 28 / 40 / 44&lt;br /&gt;
* RP2350 SPI1 MOSI: 11 / 15 / 27 / 31 / 43 / 47&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8487</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8487"/>
		<updated>2026-09-11T15:28:55Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* I2S */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 UART0 TX:  0 / 12 / 16 / 28 / 32 / 44&lt;br /&gt;
* RP2350 UART0 RX:  1 / 13 / 17 / 29 / 33 / 45&lt;br /&gt;
&lt;br /&gt;
* RP2350 UART1 TX: 4 / 8 / 20 / 24 / 36 / 40&lt;br /&gt;
* RP2350 UART1 RX: 5 / 9 / 21 / 25 / 37 / 41&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C0 SCL: 1 / 5 / 9 / 13 / 17 / 21 / 25 / 29 / 33 / 37 / 41 / 45&lt;br /&gt;
* RP2350 I2C0 SDA: 0 / 4 / 8 / 12 / 16 / 20 / 24 / 28 / 32 / 36 / 40 / 44&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C1 SCL: 3 / 7 / 11 / 15 / 19 / 23 / 27 / 31 / 35 / 39 / 43 / 47&lt;br /&gt;
* RP2350 I2C1 SDA: 2 / 6 / 10 / 14 / 18 / 22 / 26 / 30 / 34 / 38 / 42 / 46&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI0 SCK: 2 / 6 / 18 / 22 / 34 / 38 &lt;br /&gt;
* RP2350 SPI0 MISO: 0 / 4 / 16 / 20 / 32 / 36&lt;br /&gt;
* RP2350 SPI0 MOSI: 3 / 7 / 19 / 23 / 35 / 39&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI1 SCK: 10 / 14 / 26 / 30 / 42 / 46&lt;br /&gt;
* RP2350 SPI1 MISO: 8 / 12 / 24 / 28 / 40 / 44&lt;br /&gt;
* RP2350 SPI1 MOSI: 11 / 15 / 27 / 31 / 43 / 47&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8486</id>
		<title>Streamline Peripheral Pin Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Peripheral_Pin_Mapping&amp;diff=8486"/>
		<updated>2026-09-11T15:26:39Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* I2S */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0C0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that all MCUs can be mapped identically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#CC0&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means it is missing the peripheral.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#F44&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; means that pins are not same across all MCUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#0FF&amp;quot;&amp;gt;field&amp;lt;/span&amp;gt; is I2Sx_MCK only exist on one pin.&lt;br /&gt;
&lt;br /&gt;
=== RP2350 ===&lt;br /&gt;
&lt;br /&gt;
Trying to avoid 12 - 19 as these can be used for HSTX but they should be wired to backplane.&lt;br /&gt;
&lt;br /&gt;
== SWD ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|SWDIO&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP Pico Dedicated pin&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SWCLK&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SWO&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 UART0 TX:  0 / 12 / 16 / 28 / 32 / 44&lt;br /&gt;
* RP2350 UART0 RX:  1 / 13 / 17 / 29 / 33 / 45&lt;br /&gt;
&lt;br /&gt;
* RP2350 UART1 TX: 4 / 8 / 20 / 24 / 36 / 40&lt;br /&gt;
* RP2350 UART1 RX: 5 / 9 / 21 / 25 / 37 / 41&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| PA9&lt;br /&gt;
| GPIO0&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Connect default&amp;lt;br/&amp;gt;RP2350 UART0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| PA10&lt;br /&gt;
| GPIO1&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART1A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| PA3&lt;br /&gt;
| GPIO45&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART2A&lt;br /&gt;
| bgcolor=#0C0|TX&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| PD5&lt;br /&gt;
| GPIO4&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 UART1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|RX&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| PD6&lt;br /&gt;
| GPIO5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD8&lt;br /&gt;
| PD8&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| PD9&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART3A2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA0&lt;br /&gt;
| PA0&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| PA1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART4A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | UART5&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | USART6&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CAN ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN1A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD1&lt;br /&gt;
| PD1&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD0&lt;br /&gt;
| PD0&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13 &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | CAN2A&lt;br /&gt;
| bgcolor=#CC0|TX&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|RX&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB6&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== USB ==&lt;br /&gt;
STM32F407=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
STM32L475=FS host/device/otg no crystal&lt;br /&gt;
&lt;br /&gt;
STM32H562=FS PD&lt;br /&gt;
&lt;br /&gt;
STM32C071=FS no crystal&lt;br /&gt;
&lt;br /&gt;
STM32C551=FS host/device&lt;br /&gt;
&lt;br /&gt;
STM32H723=HS/FS host/device/otg&lt;br /&gt;
&lt;br /&gt;
RP2354=FS host/device&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | All&lt;br /&gt;
| bgcolor=#0C0|DM&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| PA11&lt;br /&gt;
| DM&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 dedicated pins&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|DP&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| PA12&lt;br /&gt;
| DP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C0 SCL: 1 / 5 / 9 / 13 / 17 / 21 / 25 / 29 / 33 / 37 / 41 / 45&lt;br /&gt;
* RP2350 I2C0 SDA: 0 / 4 / 8 / 12 / 16 / 20 / 24 / 28 / 32 / 36 / 40 / 44&lt;br /&gt;
&lt;br /&gt;
* RP2350 I2C1 SCL: 3 / 7 / 11 / 15 / 19 / 23 / 27 / 31 / 35 / 39 / 43 / 47&lt;br /&gt;
* RP2350 I2C1 SDA: 2 / 6 / 10 / 14 / 18 / 22 / 26 / 30 / 34 / 38 / 42 / 46&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| PB6&lt;br /&gt;
| GPIO9&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 ICL0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| PB7&lt;br /&gt;
| GPIO8&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C1A&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| PB8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C2&lt;br /&gt;
| bgcolor=#0C0|SCL&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | RP2350 I2C1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|SDA&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | I2C3&lt;br /&gt;
| bgcolor=#F44|SCL&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#F44|PC0&lt;br /&gt;
| PA8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA8&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDA&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#F44|PC1&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| TBD&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI ==&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI0 SCK: 2 / 6 / 18 / 22 / 34 / 38 &lt;br /&gt;
* RP2350 SPI0 MISO: 0 / 4 / 16 / 20 / 32 / 36&lt;br /&gt;
* RP2350 SPI0 MOSI: 3 / 7 / 19 / 23 / 35 / 39&lt;br /&gt;
&lt;br /&gt;
* RP2350 SPI1 SCK: 10 / 14 / 26 / 30 / 42 / 46&lt;br /&gt;
* RP2350 SPI1 MISO: 8 / 12 / 24 / 28 / 40 / 44&lt;br /&gt;
* RP2350 SPI1 MOSI: 11 / 15 / 27 / 31 / 43 / 47&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI1&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI1A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | PB3 conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI2A&lt;br /&gt;
| bgcolor=#0C0|SCK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | RP2350 SPI0&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MISO&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#0C0|MOSI&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | SPI3A&lt;br /&gt;
| bgcolor=#CC0|SCK&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| &lt;br /&gt;
| Conflicts with SWO&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MISO&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|MOSI&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDIO ==&lt;br /&gt;
STM32F407: SDIO&lt;br /&gt;
&lt;br /&gt;
STM32L475: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32H562: SDMMC&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: SDMMC&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0|CMD&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| PD2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PD2&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| PC8&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC8&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| PC9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC9&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| GPIO32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ethernet (RMII) ==&lt;br /&gt;
STM32F407: &lt;br /&gt;
&lt;br /&gt;
STM32L475: &lt;br /&gt;
&lt;br /&gt;
STM32H562: &lt;br /&gt;
&lt;br /&gt;
STM32C071: &lt;br /&gt;
&lt;br /&gt;
STM32C551: &lt;br /&gt;
&lt;br /&gt;
STM32H723:&lt;br /&gt;
&lt;br /&gt;
RP2354: With PIO, https://github.com/rscott2049/pico-rmii-ethernet_nce &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| MDIO&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA2&lt;br /&gt;
| GPIO44&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| REF_CLK&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA1&lt;br /&gt;
| GPIO41&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| MDC&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC1&lt;br /&gt;
| GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TX_EN&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| GPIO2&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| TXD0&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44| TXD1&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#F44 | PB15&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD0&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| RXD1&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PC5&lt;br /&gt;
| GPIO11&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CRS_DV&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| bgcolor=#CC0 | N/A&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ULPI ==&lt;br /&gt;
STM32F407: ULPI&lt;br /&gt;
&lt;br /&gt;
STM32L475: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H562: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C071: N/A&lt;br /&gt;
&lt;br /&gt;
STM32C551: N/A&lt;br /&gt;
&lt;br /&gt;
STM32H723: ULPI&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Only&lt;br /&gt;
| bgcolor=#CC0| STP&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC0&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| DIR&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| NXT&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0| CK&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| bgcolor=#CC0| N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0| N/A &lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D0&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D1&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB0&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D2&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB1&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D3&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D4&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D5&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D6&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|D7&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2S ==&lt;br /&gt;
STM32F407: I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32L475: SAI1, SAI2  (serial audio interface)&lt;br /&gt;
&lt;br /&gt;
STM32H562: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32C071: I2S1 (half duplex only)&lt;br /&gt;
&lt;br /&gt;
STM32C551: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
STM32H723: I2S1, I2S2, I2S3&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S1&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB8&lt;br /&gt;
| PC4&lt;br /&gt;
| bgcolor=#F44|PA6, PA11, PD5, PB4, PB6&lt;br /&gt;
| PC4&lt;br /&gt;
| PC4&lt;br /&gt;
| GPIO10&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB5&lt;br /&gt;
| PA6&lt;br /&gt;
| bgcolor=#F44|PA2,PA7,PA12,PB5,PD6,PB6††&lt;br /&gt;
| PA6&lt;br /&gt;
| PA6&lt;br /&gt;
| GPIO40&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PC3&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| PA7&lt;br /&gt;
| GPIO43&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB10&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| GPIO42&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|WS&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#F44|PB9&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#F44|PA1,PA5,PD8,PB3,PB6&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| GPIO27&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2&lt;br /&gt;
| bgcolor=#F44|MCK&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#F44|PB14&lt;br /&gt;
| PC6&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC6&lt;br /&gt;
| PC6&lt;br /&gt;
| GPIO26&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDI&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#F44|PC12&lt;br /&gt;
| PC2&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC2&lt;br /&gt;
| PC2&lt;br /&gt;
| GPIO25&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|SDO&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#F44|PD11&lt;br /&gt;
| PC3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC3&lt;br /&gt;
| PC3&lt;br /&gt;
| GPIO21&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#F44|CK&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#F44|PD10&lt;br /&gt;
| PB10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB10&lt;br /&gt;
| PB10&lt;br /&gt;
| GPIO3&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB12&lt;br /&gt;
| PB12&lt;br /&gt;
| GPIO24&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S2a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| PD9&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB14&lt;br /&gt;
| PB14&lt;br /&gt;
| GPIO20&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB15&lt;br /&gt;
| PB15&lt;br /&gt;
| GPIO23&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB13&lt;br /&gt;
| PB13&lt;br /&gt;
| GPIO22&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB9&lt;br /&gt;
| PB9&lt;br /&gt;
| GPIO28&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3&lt;br /&gt;
| bgcolor=#CC0|MCK&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC7&lt;br /&gt;
| PC7&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC11&lt;br /&gt;
| PC11&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC12&lt;br /&gt;
| PC12&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PC10&lt;br /&gt;
| PC10&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | I2S3a&lt;br /&gt;
| bgcolor=#0FF|MCK&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| bgcolor=#0FF|N/A&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDI&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB4&lt;br /&gt;
| PB4&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|SDO&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB5&lt;br /&gt;
| PB5&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|CK&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PB3&lt;br /&gt;
| PB3&lt;br /&gt;
| TBD&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|WS&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA15,PB8,PE4 †††&lt;br /&gt;
| PA15&lt;br /&gt;
| TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes; &lt;br /&gt;
&lt;br /&gt;
†† The STM32C071 has only one half-duplex I2S, and the _SD pin can either be in INPUT or OUTPUT mode. Many pins, how do we map?&lt;br /&gt;
&lt;br /&gt;
††† I2S3_WS is ONLY mapped on PA15 (used for SWDIO), except on STM32C551 which ALSO has it on PB8.&lt;br /&gt;
&lt;br /&gt;
== DACs ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |DAC1&lt;br /&gt;
| bgcolor=#CC0|OUT1&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA4&lt;br /&gt;
| PA4&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|-&lt;br /&gt;
| bgcolor=#CC0|OUT2&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| PA5&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADCs ==&lt;br /&gt;
ADCs are so numerous that comparative tables are difficult to establish.&lt;br /&gt;
&lt;br /&gt;
STM32F407; 12 channels common for ADC1, ADC2 and ADC3. 4 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32F407; 4 channels common for ADC1, ADC2 and ADC3. 12 channels for ADC1 and ADC2&lt;br /&gt;
&lt;br /&gt;
STM32H562; All 16 channels common for ADC1 and ADC2, can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
STM32C071; Only ADC1, 19 external channels.&lt;br /&gt;
&lt;br /&gt;
STM32C551; 7 channels common for ADC1 and ADC2.&lt;br /&gt;
&lt;br /&gt;
STM32H723; ADC1 and ADC2 are 16 bits, ADC3 is 12 bits. All 3 can also be configured as 8 differential pair inputs.&lt;br /&gt;
&lt;br /&gt;
RP2354; One ADC, 12 bits, 0.5 Msps&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Variant&lt;br /&gt;
! PIN &lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC1&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA8,PA13-PA14,PC0-PC5,PB0-PB2,PB10-PB12&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PA0-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| GPIO40-GPIO47&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 19&lt;br /&gt;
| 12&lt;br /&gt;
| 15&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| 0.5&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC2&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| PA0-PA7,PC0-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
| PA0-PA3,PC1-PC5,PB0-PB2&lt;br /&gt;
| PA2-PA7,PC0-PC2,PC4-PC5,PB0-PB1&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| 16&lt;br /&gt;
| N/A&lt;br /&gt;
| 12&lt;br /&gt;
| 13&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| 2.25&lt;br /&gt;
| 3.6&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |ADC3&lt;br /&gt;
| Pins&lt;br /&gt;
| PA0-PA7,PC0-PC3&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| PC0-PC3&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Channels&lt;br /&gt;
| 6&lt;br /&gt;
| 4&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 4 (12 bits)&lt;br /&gt;
| N/A&lt;br /&gt;
|-&lt;br /&gt;
| Msps&lt;br /&gt;
| 2.4&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| 5&lt;br /&gt;
| N/A&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8485</id>
		<title>Streamline Header Mapping</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Header_Mapping&amp;diff=8485"/>
		<updated>2026-09-11T15:26:37Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Streamline]][[Category:Work in progress]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed; overflow-wrap:break-word;&amp;quot;&lt;br /&gt;
! Position &lt;br /&gt;
! Pin Name&lt;br /&gt;
! STM32F407&lt;br /&gt;
! STM32L475&lt;br /&gt;
! STM32H562&lt;br /&gt;
! STM32C071&lt;br /&gt;
! STM32C551&lt;br /&gt;
! STM32H723&lt;br /&gt;
! RP2354&lt;br /&gt;
|-&lt;br /&gt;
| A4&lt;br /&gt;
| PA2&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TXETH_MDIO&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX&lt;br /&gt;
| USART2_TX,ETH_MDIO&lt;br /&gt;
| GPIO44: UART1_TX, ETH_MDIO&lt;br /&gt;
|-&lt;br /&gt;
| A5&lt;br /&gt;
| PA1&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX, ETH_RMII_REF_CLK&lt;br /&gt;
| &lt;br /&gt;
| UART4_RX&lt;br /&gt;
| UART4_RX,ETH_RMII_REF_CLK&lt;br /&gt;
| GPIO41: ETH_RMII_REF_CLK&lt;br /&gt;
|-&lt;br /&gt;
| A6&lt;br /&gt;
| PA0&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
| UART4_TX&lt;br /&gt;
| UART4_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A7&lt;br /&gt;
| PC3&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI&lt;br /&gt;
| SPI2_MOSI,ULPI_NXT&lt;br /&gt;
| GPIO21: I2S2_SDO&lt;br /&gt;
|-&lt;br /&gt;
| A8&lt;br /&gt;
| PC2&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO&lt;br /&gt;
| SPI2_MISO,ULPI_DIR&lt;br /&gt;
| GPIO25: I2S2_SDI&lt;br /&gt;
|-&lt;br /&gt;
| A9&lt;br /&gt;
| PC1&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| I2C3_SDA&lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_MDC&lt;br /&gt;
| GPIO47: ETH_MDC&lt;br /&gt;
|-&lt;br /&gt;
| A10&lt;br /&gt;
| PC0&lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_STP&lt;br /&gt;
| GPIO46&lt;br /&gt;
|-&lt;br /&gt;
| A11&lt;br /&gt;
| PC15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A12&lt;br /&gt;
| PC14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A13&lt;br /&gt;
| PC13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A14&lt;br /&gt;
| PE6&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO36&lt;br /&gt;
|-&lt;br /&gt;
| A15&lt;br /&gt;
| PE5&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO37&lt;br /&gt;
|-&lt;br /&gt;
| A16&lt;br /&gt;
| PE4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO38&lt;br /&gt;
|-&lt;br /&gt;
| A17&lt;br /&gt;
| PE3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO39&lt;br /&gt;
|-&lt;br /&gt;
| A18&lt;br /&gt;
| PE2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A20&lt;br /&gt;
| PE1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A21&lt;br /&gt;
| PE0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A22&lt;br /&gt;
| PB9&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| I2C1A_SDA&lt;br /&gt;
| GPIO28: I2C0_SDA,I2S2A_WS&lt;br /&gt;
|-&lt;br /&gt;
| A23&lt;br /&gt;
| PB8&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| I2C1A_SCL&lt;br /&gt;
| GPIO29: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A24&lt;br /&gt;
| PB7&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| USART1A_RX,I2C1_SDA&lt;br /&gt;
| GPIO8: I2C0_SDA&lt;br /&gt;
|-&lt;br /&gt;
| A25&lt;br /&gt;
| PB6&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,I2C1_SCL&lt;br /&gt;
| USART1A_TX,CAN2A_TX,I2C1_SCL&lt;br /&gt;
| GPIO9: I2C0_SCL&lt;br /&gt;
|-&lt;br /&gt;
| A26&lt;br /&gt;
| PB5&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| SPI1A_MOSI&lt;br /&gt;
| SPI1A_MOSI,SPI3_MOSI&lt;br /&gt;
| CAN2A_RX,SPI1A_MOSI,SPI3_MOSI,ULPI_D7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A28&lt;br /&gt;
| PB4&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| SPI1A_MISO,SPI3_MISO&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A29&lt;br /&gt;
| PB3&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| SPI1A_SCK,SPI3_SCK&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A30&lt;br /&gt;
| PD7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A31&lt;br /&gt;
| PD6&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| USART2A_RX&lt;br /&gt;
| GPIO5: UART1 TX&lt;br /&gt;
|-&lt;br /&gt;
| A32&lt;br /&gt;
| PD5&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| USART2A_TX&lt;br /&gt;
| GPIO4: UART1_TX&lt;br /&gt;
|-&lt;br /&gt;
| A33&lt;br /&gt;
| PD4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A34&lt;br /&gt;
| PD3&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A35&lt;br /&gt;
| PD2&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| &lt;br /&gt;
| UART5_RX&lt;br /&gt;
| UART5_RX,SDIO_CMD&lt;br /&gt;
| GPIO30&lt;br /&gt;
|-&lt;br /&gt;
| A36&lt;br /&gt;
| PD1&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| CAN1A_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A37&lt;br /&gt;
| PD0&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| CAN1A_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A39&lt;br /&gt;
| PC12&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| &lt;br /&gt;
| UART5_TX,SPI3_MOSI&lt;br /&gt;
| UART5_TX,SPI3_MOSI,SDIO_CK&lt;br /&gt;
| GPIO31&lt;br /&gt;
|-&lt;br /&gt;
| A40&lt;br /&gt;
| PC11&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO&lt;br /&gt;
| USART3A2_RX,UART4A_RX,SPI3_MISO,SDIO_D3&lt;br /&gt;
| GPIO32&lt;br /&gt;
|-&lt;br /&gt;
| A41&lt;br /&gt;
| PC10&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| &lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK&lt;br /&gt;
| USART3A2_TX,UART4A_TX,SPI3_SCK,SDIO_D2&lt;br /&gt;
| GPIO33&lt;br /&gt;
|-&lt;br /&gt;
| A42&lt;br /&gt;
| PA15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| A43&lt;br /&gt;
| PA14&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
| SWCLK&lt;br /&gt;
|-&lt;br /&gt;
| A44&lt;br /&gt;
| PA11&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM,CAN1_RX&lt;br /&gt;
| USB_DM&lt;br /&gt;
|-&lt;br /&gt;
| A45&lt;br /&gt;
| PA12&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP,CAN1_TX&lt;br /&gt;
| USB_DP&lt;br /&gt;
|-&lt;br /&gt;
| A46&lt;br /&gt;
| PA13&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
| SWDIO&lt;br /&gt;
|-&lt;br /&gt;
| B4&lt;br /&gt;
| PA3&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX&lt;br /&gt;
| USART2_RX,ULPI_D0&lt;br /&gt;
| GPIO45: UART1_RX&lt;br /&gt;
|-&lt;br /&gt;
| B5&lt;br /&gt;
| PA4&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO27: I2S1_WS&lt;br /&gt;
|-&lt;br /&gt;
| B6&lt;br /&gt;
| PA5&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK&lt;br /&gt;
| SPI1_SCK,ULPI_CK&lt;br /&gt;
| GPIO42: SPI0_SCK,I2S1_CK&lt;br /&gt;
|-&lt;br /&gt;
| B7&lt;br /&gt;
| PA6&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| SPI1_MISO&lt;br /&gt;
| GPIO40: SPI0_MISO,I2S1_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B8&lt;br /&gt;
| PA7&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI&lt;br /&gt;
| SPI1_MOSI,ETH_RMII_CRS_DV&lt;br /&gt;
| GPIO43: SPI0_MOSI,I2S1_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B9&lt;br /&gt;
| PC4&lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D0&lt;br /&gt;
| GPIO10: ETH_RMII_RX_D0,I2S1_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B10&lt;br /&gt;
| PC5&lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ETH_RMII_RX_D1&lt;br /&gt;
| GPIO11: ETH_RMII_RX_D1&lt;br /&gt;
|-&lt;br /&gt;
| B11&lt;br /&gt;
| PB0&lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D1&lt;br /&gt;
| GPIO12: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B12&lt;br /&gt;
| PB1&lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| ULPI_D2&lt;br /&gt;
| GPIO13: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B13&lt;br /&gt;
| PB2&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO14: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B14&lt;br /&gt;
| PE7&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO15: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B15&lt;br /&gt;
| PE8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO16: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B16&lt;br /&gt;
| PE9&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO17: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B17&lt;br /&gt;
| PE10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO18: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B18&lt;br /&gt;
| PE11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| GPIO19: HSTX&lt;br /&gt;
|-&lt;br /&gt;
| B20&lt;br /&gt;
| PE12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B21&lt;br /&gt;
| PE13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B22&lt;br /&gt;
| PE14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B23&lt;br /&gt;
| PE15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B24&lt;br /&gt;
| PB10&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK&lt;br /&gt;
| USART3_TX,I2C2_SCL,SPI2_SCK,ULPI_D3&lt;br /&gt;
| GPIO3: I2C1_SCL,I2S2_CK&lt;br /&gt;
|-&lt;br /&gt;
| B25&lt;br /&gt;
| PB11&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ETH_RMII_TX_EN&lt;br /&gt;
| I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA&lt;br /&gt;
| USART3_RX,I2C2_SDA,ULPI_D4,ETH_RMII_TX_EN&lt;br /&gt;
| GPIO2: I2C1_SDA,ETH_RMII_TX_EN&lt;br /&gt;
|-&lt;br /&gt;
| B26&lt;br /&gt;
| PB12&lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ETH_RMII_TXD0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| CAN2_RX,ULPI_D5,ETH_RMII_TXD0&lt;br /&gt;
| GPIO24: ETH_RMII_TXD0,I2S2_WS&lt;br /&gt;
|-&lt;br /&gt;
| B28&lt;br /&gt;
| PB13&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1 &lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| SPI2A_SCK&lt;br /&gt;
| CAN2_TX,SPI2A_SCK,ULPI_D6,ETH_RMII_TXD1&lt;br /&gt;
| GPIO22: SPI0_SCK,ETH_RMII_TXD1,I2S2A_CK&lt;br /&gt;
|-&lt;br /&gt;
| B29&lt;br /&gt;
| PB14&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| SPI2A_MISO&lt;br /&gt;
| GPIO20: SPI0_RX,I2S2A_SDI&lt;br /&gt;
|-&lt;br /&gt;
| B30&lt;br /&gt;
| PB15&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI,ETH_RMII_TXD1&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| SPI2A_MOSI&lt;br /&gt;
| GPIO23: SPI0_TX,I2S2A_SDO&lt;br /&gt;
|-&lt;br /&gt;
| B31&lt;br /&gt;
| PD8&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| USART3A1_TX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B32&lt;br /&gt;
| PD9&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| USART3A1_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B33&lt;br /&gt;
| PD10&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B34&lt;br /&gt;
| PD11&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B35&lt;br /&gt;
| PD12&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B36&lt;br /&gt;
| PD13&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B37&lt;br /&gt;
| PD14&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B39&lt;br /&gt;
| PD15&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| bgcolor=#CC0|N/A&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B40&lt;br /&gt;
| PC6&lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_TX&lt;br /&gt;
| GPIO26: I2S2_MCK&lt;br /&gt;
|-&lt;br /&gt;
| B41&lt;br /&gt;
| PC7&lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| UART6_RX&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B42&lt;br /&gt;
| PC8&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D0&lt;br /&gt;
| GPIO35&lt;br /&gt;
|-&lt;br /&gt;
| B43&lt;br /&gt;
| PC9&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| SDIO_D1&lt;br /&gt;
| GPIO34&lt;br /&gt;
|-&lt;br /&gt;
| B44&lt;br /&gt;
| PA8&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| B45&lt;br /&gt;
| PA9&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| USART1_TX&lt;br /&gt;
| GPIO0: UART0_TX&lt;br /&gt;
|-&lt;br /&gt;
| B46&lt;br /&gt;
| PA10&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| USART1_RX&lt;br /&gt;
| GPIO1: UART0_RX&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
</feed>