i2c: fix slave event kind propagation — explicit I2cSlaveEvent impl on backend
diff --git a/services/i2c/api/src/seam.rs b/services/i2c/api/src/seam.rs index 0b30eb7..37fc61d 100644 --- a/services/i2c/api/src/seam.rs +++ b/services/i2c/api/src/seam.rs
@@ -27,12 +27,21 @@ use crate::protocol::I2cError; /// Extension trait for fetching the next slave event with its full event kind. -/// Enables backends to return both the hardware event kind (ReadRequest, Stop, etc.) -/// alongside the rx length, so the server-runtime can propagate correct metadata. -/// Default impl delegates to `poll_slave_data()` for backward compatibility. +/// +/// Enables backends to return both the hardware event kind (ReadRequest, Stop, +/// etc.) alongside the rx length, so the server-runtime can propagate correct +/// event metadata. Backends that have richer ISR event information should +/// implement this directly rather than relying on the default. +/// +/// The default impl delegates to [`I2cSlaveBuffer::poll_slave_data`] and +/// always reports [`I2cIsrEvent::SlaveWrRecvd`] — correct for data-received +/// events but loses ReadRequest and Stop distinctions. Override to propagate +/// the full hardware event. +/// +/// Implement this explicitly on every backend; do not rely on a blanket impl, +/// which would prevent overriding the default via trait dispatch. pub trait I2cSlaveEvent: I2cSlaveBuffer { /// Return the next slave event and rx length, if any. - /// Default impl uses `poll_slave_data()` and reports DataReceived kind. fn try_next_slave_event(&mut self) -> Result<Option<(I2cIsrEvent, usize)>, Self::Error> { Ok(self .poll_slave_data()? @@ -40,9 +49,6 @@ } } -/// Blanket impl so all I2cSlaveBuffer types get the default behavior. -impl<T: I2cSlaveBuffer> I2cSlaveEvent for T {} - /// Map a wire status code onto the `embedded_hal::i2c::ErrorKind` taxonomy so /// the client can satisfy `embedded_hal::i2c::Error`. pub fn error_kind(err: I2cError) -> ErrorKind {
diff --git a/target/ast10x0/backend/i2c/src/lib.rs b/target/ast10x0/backend/i2c/src/lib.rs index 2e206af..e546ea3 100644 --- a/target/ast10x0/backend/i2c/src/lib.rs +++ b/target/ast10x0/backend/i2c/src/lib.rs
@@ -41,7 +41,8 @@ use ast1060_pac::{i2c::RegisterBlock, i2cbuff::RegisterBlock as BuffRegisterBlock}; use embedded_hal::i2c::{ErrorType, I2c, Operation, SevenBitAddress}; -use openprot_hal_blocking::i2c_hardware::slave::{I2cSlaveBuffer, I2cSlaveCore}; +use i2c_api::seam::I2cSlaveEvent; +use openprot_hal_blocking::i2c_hardware::slave::{I2cIsrEvent, I2cSlaveBuffer, I2cSlaveCore}; use openprot_hal_blocking::i2c_hardware::I2cBusRecovery; pub use ast10x0_peripherals::i2c::{ @@ -198,6 +199,17 @@ } } +/// Explicit impl so the server-runtime receives the actual hardware event kind +/// (ReadRequest, Stop, etc.) rather than the default DataReceived from +/// `poll_slave_data()`. The inner `Ast1060I2c::try_next_slave_event` is an +/// inherent method; routing through this explicit trait impl is the only way +/// to reach it via trait dispatch (a blanket on I2cSlaveBuffer would shadow it). +impl I2cSlaveEvent for Ast1060I2cBackend { + fn try_next_slave_event(&mut self) -> Result<Option<(I2cIsrEvent, usize)>, Self::Error> { + self.make_driver().try_next_slave_event() + } +} + /// Resolve a bus index to its `(I2C, I2CBUFF)` register-block pointers. /// /// AST1060 exposes 14 controllers; instances 1..=13 are `derivedFrom` I2C0 in