@@ -157,8 +157,23 @@ static int i2c_silabs_transfer_dma(const struct device *dev, struct i2c_msg *msg
157157#endif /* CONFIG_I2C_TARGET */
158158
159159 while (i < num_msgs ) {
160- data -> last_transfer = (i + 1 ) == num_msgs ;
161- if (msgs [i ].flags & I2C_MSG_READ ) {
160+ uint8_t msgs_in_transfer = 1 ;
161+
162+ /* Combined DMA write-read (repeated start) */
163+ if ((msgs [i ].flags & I2C_MSG_WRITE ) == 0 && (i + 1 < num_msgs ) &&
164+ (msgs [i + 1 ].flags & I2C_MSG_READ )) {
165+ msgs_in_transfer = 2 ;
166+ }
167+ data -> last_transfer = (i + msgs_in_transfer ) == num_msgs ;
168+
169+ if (msgs_in_transfer == 2 ) {
170+ if (sl_i2c_transfer_non_blocking (i2c_handle , msgs [i ].buf , msgs [i ].len ,
171+ msgs [i + 1 ].buf , msgs [i + 1 ].len , NULL ,
172+ NULL ) != 0 ) {
173+ k_sem_give (& data -> bus_lock );
174+ return - EIO ;
175+ }
176+ } else if (msgs [i ].flags & I2C_MSG_READ ) {
162177 /* Start DMA receive */
163178 if (sl_i2c_receive_non_blocking (i2c_handle , msgs [i ].buf , msgs [i ].len , NULL ,
164179 NULL ) != 0 ) {
@@ -186,7 +201,7 @@ static int i2c_silabs_transfer_dma(const struct device *dev, struct i2c_msg *msg
186201 break ;
187202 }
188203 }
189- i ++ ;
204+ i += msgs_in_transfer ;
190205 }
191206
192207 return err ;
@@ -207,8 +222,11 @@ static int i2c_silabs_transfer_sync(const struct device *dev, struct i2c_msg *ms
207222 i2c_silabs_pm_policy_state_lock_get (dev );
208223
209224 while (i < num_msgs ) {
225+ uint8_t msgs_in_transfer = 1 ;
226+
210227 if ((msgs [i ].flags & I2C_MSG_WRITE ) == 0 && (i + 1 < num_msgs ) &&
211228 (msgs [i + 1 ].flags & I2C_MSG_READ )) {
229+ msgs_in_transfer = 2 ;
212230 if (sl_i2c_transfer (i2c_handle , msgs [i ].buf , msgs [i ].len , msgs [i + 1 ].buf ,
213231 msgs [i + 1 ].len ) != 0 ) {
214232 k_sem_give (& data -> bus_lock );
@@ -228,7 +246,7 @@ static int i2c_silabs_transfer_sync(const struct device *dev, struct i2c_msg *ms
228246 return - ETIMEDOUT ;
229247 }
230248 }
231- i ++ ;
249+ i += msgs_in_transfer ;
232250 }
233251
234252 /* Release the bus lock semaphore */
@@ -434,7 +452,8 @@ void i2c_silabs_isr_handler(const struct device *dev)
434452#else
435453 sli_i2c_leader_dispatch_interrupt (sl_i2c_instance );
436454#endif
437- if (sl_i2c_instance -> transfer_event != SL_I2C_EVENT_IN_PROGRESS ) {
455+ if (sl_i2c_instance -> transfer_event != SL_I2C_EVENT_IN_PROGRESS &&
456+ sl_i2c_instance -> rstart == 0 ) {
438457 if (!data -> asynchronous ) {
439458 k_sem_give (& data -> transfer_sem );
440459 }
0 commit comments