Hello, I'm Felipe Balbi.

I build firmware and tools for embedded systems. I work mostly in Rust and C, with detours through Python and shell when the job calls for it. This site is where I keep notes that might be useful to someone other than me.

Embedded systems · Rust · the craft of writing software

Recent posts

  • Thirty-Six Registers, Described Twelve Times

    AddressPins { a0: AddrPinState::Gnd, a1: AddrPinState::Sda } That selects 0x48. Swap the two fields and you get 0x42. Both are addresses an INA4230 will answer to, given the right strapping. Both fields have the same type, so the compiler has nothing to say about it, and a reviewer reading the line …

    Read more →
  • CRC-16 is not a specification

    A datasheet says CRC-16. You implement CRC-16. The numbers do not match, and neither implementation has a bug.

    Read more →
  • Making Smaller Things

    Take a temperature sensor about as simple as a part can get. It hangs off an I²C bus and has exactly two registers. Register 0x00 holds the temperature result — signed sixteen bits, one LSB equal to 1/128 of a degree Celsius. Register 0x01 holds the configuration, three fields packed into sixteen bi…

    Read more →
  • Pico de Gallo: Schema 0.7, and a Zephyr Module That Grew Up

    Pico de Gallo turns an RP2350 into a USB-attached bridge so a host program can drive real I²C, SPI, UART, GPIO, PWM, ADC and 1-Wire without cross-compiling or flashing anything. Yesterday all eight wire-coupled crates moved at once, for wire schema 0.7. The cycle started as housekeeping. The Zephyr …

    Read more →
  • Pico de Gallo: Real Buses for Zephyr's native_sim

    Pico de Gallo turns an RP2350 into a USB-attached bridge so a host program can drive real I²C, SPI, UART, GPIO, PWM, ADC and 1-Wire without cross-compiling or flashing anything. Zephyr has always had real buses, of course. But native_sim — the board you build when you want a Zephyr application to ru…

    Read more →
  • Tamal: Binding to Silicon

    system is a machine with no address. That is what the last post left. A hundred and fifteen lines that wire a UART to a loader to two memories to an engine, and produce a serial line, a four-lane drive, three sidebands and a blinking LED — all of it generic in dom, which is to say it never says how …

    Read more →
  • Tamal: Everything, Wired

    The pads exist now, and they are wired to nothing. That is the odd position the series has arrived in. We have read a CRC unit, a baud generator, a transmitter, a receiver and the umbrella over them; a COBS codec and the loader that streams it; two block RAMs; an engine, in eight instalments, from i…

    Read more →
  • Tamal: Out to the Pins

    The serdes post ended with a promise and an apology. It had just finished arguing that a (value, enable) pair is the whole of tri-state — three wire states carried in two bits — and then it admitted that none of it was real yet. Every Lanes the engine computes is still just numbers, it said; a descr…

    Read more →
  • Tamal: The Record and the Ring

    The wire post left a word-stream sealed. encodeResult wrapped a drained ring — a REVISION word, some records, a HALT terminator — behind an opcode and never looked inside. This post looks inside. It is the smallest file of the whole descent, sixty-four lines, and it is the pure twin the bus post kep…

    Read more →
  • Tamal: Frames on the Wire

    The engine is open entire. The outside-in descent that began with the shape post’s map of eight boxes ended when the serdes finale opened the last of them, and everything the fabric does — fetch, decode, compute, drive the pins, record what happened — has now been read leaf by leaf. But a running en…

    Read more →

All posts →