Creating a multi platform Rust Driver: FT232H Breakout Board
In the previous part of the series we explored the embedded-hal traits and how they can be used to create platform agnostic drivers in Rust. In this part, we will focus on how we can use the FT232H breakout board to interact with our I2C device from a desktop environment.

An ordinary laptop or desktop computer does not have native I2C support, so we need to use a USB to I2C bridge to communicate with our device. The FT232H breakout board made by adafruit is a popular choice for this purpose, as it provides a simple and reliable way to interface with I2C devices from a computer. It also provides GPIO, SPI and has a STEMMA QT connector for easy wiring. Allowing us to chain a bunch of I2C devices together.
Creating a multi platform Rust Driver: Embedded Hal
In this first part of the series, we’ll focus on the Embedded HAL (Hardware Abstraction Layer) and Embedded HAL Async—the foundation for writing portable Rust drivers.
What is it?

The Embedded HAL provides a set of traits that let you write platform-agnostic code, making it much easier to support multiple hardware platforms. It doesn’t just cover GPIO, I²C, and SPI—there are also traits for:
- embedded-hal-bus - provides traits for shared bus access, allowing multiple devices to share the same bus without conflicts.
- embedded-can - provides traits for Controller Area Network (CAN) communication, commonly used in automotive and industrial applications.
- And many more systems…
It’s a set of official traits maintained by the Rust Embedded Working Group that provide standardised interfaces for embedded protocols. Instead of everyone reimplementing read/write functions for I²C, SPI, or GPIO, there’s one common interface. There are two flavours: embedded-hal for blocking/synchronous operations, and embedded-hal-async for non-blocking/asynchronous ones.
Creating a multi platform Rust Driver: Overview
Writing drivers that work consistently across microcontrollers, embedded Linux boards, and desktop operating systems is deceptively hard. Different HALs, conflicting abstractions, and platform-specific quirks often lead to duplicated code or forests of #ifdef blocks.

In this blog series, we’ll explore how to design and implement a multi-platform Rust driver that avoids all of that — one codebase, many targets. We’ll look at how Rust’s trait system, strong type guarantees, built-in testing support, and CI-friendly workflow make this not only possible, but pleasant.
Dyson
After leaving Babcock, I joined Dyson as part of the New Product Innovation Software Team (NST), a multidisciplinary group working across the entire technology stack—from embedded systems and application development through to cloud services and data science. During my time in the team, I developed numerous prototypes and explored a wide range of technologies, from bare-metal microcontrollers to embedded Linux platforms.

Due to IP restrictions, I’m unable to share specific details about the prototypes, their architectures, or their intended applications. However, watch this space—several of these early concepts are making their way toward full product development.
Open Source
My Open Source Contributions
I’m a big fan of open source—where code is shared, bugs are squashed, and collaboration is the name of the game. Over the years, I’ve dabbled in all sorts of open source projects, sometimes as a developer, sometimes as a user. I especially like to get involved in Rust projects, and I hope to keep adding more to the ecosystem. You’ll find some of my favourite projects below, and even more on my GitHub profile.