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