@@ -168,9 +168,12 @@ struct i2c_ctrl_data {
168
168
enum npcx_i2c_oper_state oper_state ; /* controller operation state */
169
169
int trans_err ; /* error code during transaction */
170
170
struct i2c_msg * msg ; /* cache msg for transaction state machine */
171
+ struct i2c_msg * msg_head ;
171
172
int is_write ; /* direction of current msg */
172
173
uint8_t * ptr_msg ; /* current msg pointer for FIFO read/write */
173
174
uint16_t addr ; /* slave address of transaction */
175
+ uint8_t msg_max_num ;
176
+ uint8_t msg_curr_idx ;
174
177
uint8_t port ; /* current port used the controller */
175
178
bool is_configured ; /* is port configured? */
176
179
const struct npcx_i2c_timing_cfg * ptr_speed_confs ;
@@ -639,6 +642,24 @@ static void i2c_ctrl_handle_write_int_event(const struct device *dev)
639
642
/* Wait for STOP completed */
640
643
data -> oper_state = NPCX_I2C_WAIT_STOP ;
641
644
} else {
645
+ uint8_t next_msg_idx = data -> msg_curr_idx + 1 ;
646
+
647
+ if (next_msg_idx < data -> msg_max_num ) {
648
+ struct i2c_msg * msg ;
649
+
650
+ data -> msg_curr_idx = next_msg_idx ;
651
+ msg = data -> msg_head + next_msg_idx ;
652
+ data -> msg = msg ;
653
+ data -> ptr_msg = msg -> buf ;
654
+ if ((msg -> flags & I2C_MSG_RW_MASK ) == I2C_MSG_WRITE ) {
655
+ data -> oper_state = NPCX_I2C_WRITE_FIFO ;
656
+ } else {
657
+ data -> is_write = 0 ;
658
+ data -> oper_state = NPCX_I2C_WAIT_RESTART ;
659
+ i2c_ctrl_start (dev );
660
+ }
661
+ return ;
662
+ }
642
663
/* Disable interrupt and handle next message */
643
664
i2c_ctrl_irq_enable (dev , 0 );
644
665
}
@@ -702,6 +723,27 @@ static void i2c_ctrl_handle_read_int_event(const struct device *dev)
702
723
/* Release bus */
703
724
i2c_ctrl_hold_bus (dev , 0 );
704
725
return ;
726
+ } else if ((data -> msg -> flags & I2C_MSG_STOP ) == 0 ) {
727
+ uint8_t next_msg_idx = data -> msg_curr_idx + 1 ;
728
+
729
+ if (next_msg_idx < data -> msg_max_num ) {
730
+ struct i2c_msg * msg ;
731
+
732
+ msg = data -> msg_head + next_msg_idx ;
733
+ if ((msg -> flags & I2C_MSG_RW_MASK ) == I2C_MSG_READ ) {
734
+
735
+ data -> msg_curr_idx = next_msg_idx ;
736
+ data -> msg = msg ;
737
+ data -> ptr_msg = msg -> buf ;
738
+
739
+ /* Setup threshold of RX FIFO first */
740
+ i2c_ctrl_fifo_rx_setup_threshold_nack (
741
+ dev , msg -> len , (msg -> flags & I2C_MSG_STOP ) != 0 );
742
+ /* Release bus */
743
+ i2c_ctrl_hold_bus (dev , 0 );
744
+ return ;
745
+ }
746
+ }
705
747
}
706
748
}
707
749
@@ -1258,7 +1300,7 @@ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs,
1258
1300
{
1259
1301
struct i2c_ctrl_data * const data = i2c_dev -> data ;
1260
1302
int ret = 0 ;
1261
- uint8_t i ;
1303
+ struct i2c_msg * msg = msgs ;
1262
1304
1263
1305
#ifdef CONFIG_I2C_TARGET
1264
1306
/* I2c module has been configured to target mode */
@@ -1297,25 +1339,21 @@ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs,
1297
1339
data -> trans_err = 0 ;
1298
1340
data -> addr = addr ;
1299
1341
1342
+ data -> msg_head = msgs ;
1343
+ data -> msg_max_num = num_msgs ;
1344
+ data -> msg_curr_idx = 0 ;
1345
+
1300
1346
/*
1301
1347
* Reset i2c event-completed semaphore before starting transactions.
1302
1348
* Some interrupt events such as BUS_ERROR might change its counter
1303
1349
* when bus is idle.
1304
1350
*/
1305
1351
k_sem_reset (& data -> sync_sem );
1306
1352
1307
- for (i = 0U ; i < num_msgs ; i ++ ) {
1308
- struct i2c_msg * msg = msgs + i ;
1309
-
1310
- /* Handle write transaction */
1311
- if ((msg -> flags & I2C_MSG_RW_MASK ) == I2C_MSG_WRITE ) {
1312
- ret = i2c_ctrl_proc_write_msg (i2c_dev , msg );
1313
- } else {/* Handle read transaction */
1314
- ret = i2c_ctrl_proc_read_msg (i2c_dev , msg );
1315
- }
1316
- if (ret < 0 ) {
1317
- break ;
1318
- }
1353
+ if ((msg -> flags & I2C_MSG_RW_MASK ) == I2C_MSG_WRITE ) {
1354
+ ret = i2c_ctrl_proc_write_msg (i2c_dev , msg );
1355
+ } else { /* Handle read transaction */
1356
+ ret = i2c_ctrl_proc_read_msg (i2c_dev , msg );
1319
1357
}
1320
1358
1321
1359
/* Check STOP completed? */
0 commit comments