-
Notifications
You must be signed in to change notification settings - Fork 156
Open
Description
The current Datagram_Device interface, while functional for basic communication, presents several limitations when working with I²C and SPI peripherals:
- No type-safety: Drivers cannot enforce that they receive the correct bus type (I²C vs SPI), allowing runtime errors when incompatible buses are provided.
- Missing bus-specific features: Important features like I²C addressing, SPI chip select management, and bus-specific configuration options are not expressible through the generic datagram interface.
- Clients must handle bus-specific setup (like I²C addresses) outside of the driver, leading to scattered configuration and potential inconsistencies.
- Less flexibility: Cannot leverage bus-specific optimizations or handle bus-specific error conditions appropriately.
- Difficulty adapting to Datagram_device: The current interface requires
readv, which on some chips (e.g. nrf52) will not work.
I propose that we introduce dedicated I2C_Device and SPI_Device interfaces that provide type safety and expose bus-specific functionality while maintaining compatibility with existing code where appropriate.
Having specific types will additionally allow us to expose bus-specific errors (e.g. Nack) while providing compile-time validation of the provided bus.
// Old approach
pub const TempSensor = struct {
device: mdf.base.Datagram_Device,
pub fn init(device: mdf.base.Datagram_Device) TempSensor {
// Address handling is external
return TempSensor{ .device = device };
}
};
// New approach
pub const TempSensor = struct {
i2c: I2C_Device,
pub fn init(i2c: I2C_Device, address: I2C_Address) !TempSensor {
try i2c.set_address(address);
if (!try i2c.probe_device()) return error.SensorNotFound;
return TempSensor{ .i2c = i2c };
}
pub fn read_temperature(self: *TempSensor) !f32 {
var buffer: [2]u8 = undefined;
try self.i2c.writev_then_readv(&.{&.{0x00}}, .{&buffer}); // Register read
// ...
}
};Implementation could be done rather easily in four steps:
- Introduce new interface
- Add implementations for each port's driver.
- Update drivers to use the bus-specific interface
- Update existing examples to use new driver interface.
Steps 3 & 4 would need to be done in single PR.
Metadata
Metadata
Assignees
Labels
No labels