<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>I²C in Real Systems on Embedded Systems Development</title><link>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/</link><description>Recent content in I²C in Real Systems on Embedded Systems Development</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/index.xml" rel="self" type="application/rss+xml"/><item><title>I²C Initialization &amp; Clock Configuration</title><link>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/i2c-initialization/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/i2c-initialization/</guid><description>&lt;h1 id="ic-initialization--clock-configuration"&gt;I²C Initialization &amp;amp; Clock Configuration&lt;a class="anchor" href="#ic-initialization--clock-configuration"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Every I²C transaction depends on the peripheral being correctly initialized: GPIO pins configured as open-drain with alternate function, the I²C clock enabled via RCC, and the timing registers set to produce the desired SCL frequency. Getting any of these wrong produces symptoms that range from no activity on the bus to intermittent NACKs that appear device-dependent but are actually timing violations. The initialization code is typically short — 10 to 20 lines — but the details inside those lines determine whether the bus works reliably at 400 kHz or silently falls back to unpredictable behavior.&lt;/p&gt;</description></item><item><title>Multi-Byte Read/Write Patterns</title><link>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/i2c-multi-byte-patterns/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/i2c-multi-byte-patterns/</guid><description>&lt;h1 id="multi-byte-readwrite-patterns"&gt;Multi-Byte Read/Write Patterns&lt;a class="anchor" href="#multi-byte-readwrite-patterns"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Most I²C devices expose a register-based interface: a write transaction sends the register address, and a read transaction retrieves the data at that address. The protocol detail that makes this work is the repeated start condition — a start without a preceding stop — which allows the master to switch from write mode (sending the register address) to read mode (receiving data) without releasing the bus. Nearly every sensor, EEPROM, and I/O expander uses this pattern, and understanding the transaction structure at the byte level is essential for debugging transfers that silently return stale or incorrect data.&lt;/p&gt;</description></item><item><title>Error Recovery &amp; Bus Reset</title><link>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/i2c-error-recovery/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/i2c-error-recovery/</guid><description>&lt;h1 id="error-recovery--bus-reset"&gt;Error Recovery &amp;amp; Bus Reset&lt;a class="anchor" href="#error-recovery--bus-reset"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I²C errors fall into two categories: protocol-level errors that the hardware peripheral detects (NACK, arbitration loss, bus error) and bus-level failures that the peripheral cannot self-recover from (stuck SDA, phantom busy flag). The first category is handled by error callbacks and retry logic. The second requires manual intervention — toggling GPIOs, resetting the peripheral, or power-cycling the bus. Firmware that does not handle both categories will eventually lock up in the field, because every I²C bus will eventually encounter a stuck condition, and no amount of software reset will clear a slave device that is holding SDA low mid-byte.&lt;/p&gt;</description></item><item><title>Multi-Master &amp; Arbitration</title><link>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/i2c-multi-master/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://applied-ee.github.io/embedded/docs/digital-interfaces/i2c/i2c-multi-master/</guid><description>&lt;h1 id="multi-master--arbitration"&gt;Multi-Master &amp;amp; Arbitration&lt;a class="anchor" href="#multi-master--arbitration"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I²C was designed from the start to support multiple masters on the same bus. Arbitration — the mechanism that resolves contention when two masters transmit simultaneously — is built into the protocol at the electrical level, not as an optional extension. In practice, multi-master I²C is uncommon in small embedded systems because the firmware complexity it introduces rarely justifies the architectural benefit. Understanding the arbitration mechanism is still essential, because arbitration loss can occur even in systems that were not designed as multi-master — a stuck slave or a bus fault can trigger arbitration loss interrupts that firmware must handle gracefully.&lt;/p&gt;</description></item></channel></rss>