cleanup unsafe regions
diff --git a/target/ast10x0/peripherals/i2c/master.rs b/target/ast10x0/peripherals/i2c/master.rs
index 9aa4e74..b286fd9 100644
--- a/target/ast10x0/peripherals/i2c/master.rs
+++ b/target/ast10x0/peripherals/i2c/master.rs
@@ -211,9 +211,7 @@
 
         while offset < total_len {
             let chunk_len = core::cmp::min(constants::BUFFER_MODE_SIZE, total_len - offset);
-            // SAFETY: chunk_len = min(BUFFER_MODE_SIZE, total_len - offset), so
-            // offset + chunk_len <= total_len == bytes.len().
-            let chunk = unsafe { bytes.get_unchecked(offset..offset + chunk_len) };
+            let chunk = bytes.get(offset..offset + chunk_len).ok_or(I2cError::Invalid)?;
             let is_first = offset == 0;
             let is_last = offset + chunk_len >= total_len;
 
@@ -338,9 +336,7 @@
             }
 
             // Copy from hardware buffer AFTER successful transfer
-            // SAFETY: chunk_len = min(BUFFER_MODE_SIZE, total_len - offset), so
-            // offset + chunk_len <= total_len == buffer.len().
-            let chunk = unsafe { buffer.get_unchecked_mut(offset..offset + chunk_len) };
+            let chunk = buffer.get_mut(offset..offset + chunk_len).ok_or(I2cError::Invalid)?;
             self.copy_from_buffer(chunk)?;
 
             #[allow(clippy::cast_possible_truncation)]
@@ -446,9 +442,7 @@
 
         while offset < total_len {
             let chunk_len = core::cmp::min(constants::DMA_MODE_MAX_SIZE, total_len - offset);
-            // SAFETY: chunk_len = min(DMA_MODE_MAX_SIZE, total_len - offset), so
-            // offset + chunk_len <= total_len == bytes.len().
-            let chunk = unsafe { bytes.get_unchecked(offset..offset + chunk_len) };
+            let chunk = bytes.get(offset..offset + chunk_len).ok_or(I2cError::Invalid)?;
             let is_first = offset == 0;
             let is_last = offset + chunk_len >= total_len;
 
@@ -590,14 +584,7 @@
             // Copy from DMA buffer into caller's buffer
             {
                 let dma_buf = self.dma_buf.as_deref().ok_or(I2cError::Invalid)?;
-                // SAFETY: chunk_len = min(DMA_MODE_MAX_SIZE, total_len - offset), so
-                // offset + chunk_len <= total_len == buffer.len(). dma_buf.len() >= chunk_len
-                // is checked above before the DMA transfer starts.
-                unsafe {
-                    buffer
-                        .get_unchecked_mut(offset..offset + chunk_len)
-                        .copy_from_slice(dma_buf.get_unchecked(..chunk_len));
-                }
+                buffer.get_mut(offset..offset + chunk_len).ok_or(I2cError::Invalid)?.copy_from_slice(dma_buf.get(..chunk_len).ok_or(I2cError::Invalid)?);
             }
 
             #[allow(clippy::cast_possible_truncation)]
diff --git a/target/ast10x0/peripherals/i2c/transfer.rs b/target/ast10x0/peripherals/i2c/transfer.rs
index 73f5cb0..8694d97 100644
--- a/target/ast10x0/peripherals/i2c/transfer.rs
+++ b/target/ast10x0/peripherals/i2c/transfer.rs
@@ -137,9 +137,8 @@
             // Pack bytes into DWORD (little-endian)
             let mut dword: u32 = 0;
             for byte_pos in 0..4 {
-                if idx + byte_pos < data.len() {
-                    // SAFETY: idx + byte_pos < data.len() checked above.
-                    dword |= u32::from(unsafe { *data.get_unchecked(idx + byte_pos) }) << (byte_pos * 8);
+                if let Some(&byte) = data.get(idx + byte_pos) {
+                    dword |= u32::from(byte) << (byte_pos * 8);
                 }
             }
 
@@ -179,10 +178,8 @@
 
             // Extract bytes from DWORD (little-endian)
             for byte_pos in 0..4 {
-                if idx + byte_pos < data.len() {
-                    // SAFETY: idx + byte_pos < data.len() checked above.
-                    *unsafe { data.get_unchecked_mut(idx + byte_pos) } =
-                        ((dword >> (byte_pos * 8)) & 0xFF) as u8;
+                if let Some(slot) = data.get_mut(idx + byte_pos) {
+                    *slot = ((dword >> (byte_pos * 8)) & 0xFF) as u8;
                 }
             }