8484 || (freq_mode == SL_I2C_FREQ_FAST_MODE) \
8585 || (freq_mode == SL_I2C_FREQ_FASTPLUS_MODE))
8686
87+ #define RSTART_WRITE_INPROGRESS 1
88+ #define RSTART_READ_INPROGRESS 2
89+
8790/*******************************************************************************
8891 ************************** LOCAL FUNCTIONS ********************************
8992 ******************************************************************************/
@@ -713,6 +716,38 @@ sl_status_t sl_i2c_receive_non_blocking(sl_i2c_handle_t i2c_handle,
713716 return SL_STATUS_OK ;
714717}
715718
719+ /***************************************************************************/ /**
720+ * @brief Initiates a non-blocking combined write-read I2C transfer (Leader mode only).
721+ *
722+ * @param i2c_handle I2C handle
723+ * @param tx_buffer Pointer to transmit buffer
724+ * @param tx_len Number of bytes to transmit
725+ * @param rx_buffer Pointer to receive buffer
726+ * @param rx_len Number of bytes to receive
727+ * @param i2c_callback Callback function to notify transfer completion
728+ * @param context User context for callback
729+ * @return sl_status_t
730+ */
731+ sl_status_t sl_i2c_transfer_non_blocking (sl_i2c_handle_t i2c_handle ,
732+ const uint8_t * tx_buffer ,
733+ uint16_t tx_len ,
734+ uint8_t * rx_buffer ,
735+ uint16_t rx_len ,
736+ sl_i2c_irq_callback_t i2c_callback ,
737+ void * context )
738+ {
739+ sli_i2c_instance_t * sl_i2c_instance = (sli_i2c_instance_t * )i2c_handle ;
740+ sl_status_t status ;
741+
742+ sl_i2c_instance -> rstart = RSTART_WRITE_INPROGRESS ;
743+ sl_i2c_instance -> rx_buffer = rx_buffer ;
744+ sl_i2c_instance -> rx_len = rx_len ;
745+ sl_i2c_instance -> rx_offset = 0 ;
746+ status = sl_i2c_send_non_blocking (i2c_handle , tx_buffer , tx_len , i2c_callback , context );
747+
748+ return status ;
749+ }
750+
716751/*******************************************************************************
717752 ************************** INTERNAL FUNCTIONS *****************************
718753 ******************************************************************************/
@@ -952,7 +987,9 @@ sl_status_t sli_i2c_dma_transfer_init(sli_i2c_instance_t *i2c_instance)
952987
953988#if defined(EMDRV_DMADRV_LDMA )
954989 if (i2c_instance -> transfer_seq == SL_I2C_WRITE ) {
955- (i2c_base_addr )-> CTRL_SET = I2C_CTRL_AUTOSE ;
990+ if (i2c_instance -> rstart == 0 ) {
991+ (i2c_base_addr )-> CTRL_SET = I2C_CTRL_AUTOSE ;
992+ }
956993 i2c_instance -> tx_desc [0 ] = (LDMA_Descriptor_t )LDMA_DESCRIPTOR_LINKREL_M2P_BYTE ((void * )(addr_buffer ), & ((i2c_base_addr )-> TXDATA ), addr_buffer_count , 1 );
957994 i2c_instance -> tx_desc [1 ] = (LDMA_Descriptor_t )LDMA_DESCRIPTOR_SINGLE_M2P_BYTE ((void * )data_buffer , & ((i2c_base_addr )-> TXDATA ), data_len );
958995 } else if (i2c_instance -> transfer_seq == SL_I2C_READ ) {
@@ -1590,13 +1627,29 @@ void sli_i2c_leader_dispatch_interrupt(sli_i2c_instance_t *sl_i2c_instance)
15901627 DMADRV_StopTransfer (sl_i2c_instance -> dma_channel .dma_tx_channel );
15911628 } else if (sl_i2c_instance -> transfer_seq == SL_I2C_READ ) {
15921629 DMADRV_StopTransfer (sl_i2c_instance -> dma_channel .dma_rx_channel );
1630+ sl_i2c_instance -> rstart = 0 ;
15931631 }
15941632
15951633 (i2c_base_addr )-> CTRL = _I2C_CTRL_RESETVALUE ;
15961634
15971635 if (sl_i2c_instance -> transfer_event == SL_I2C_EVENT_IN_PROGRESS ) {
15981636 sl_i2c_instance -> transfer_event = SL_I2C_EVENT_COMPLETED ;
15991637 }
1638+ } else if (pending_irq & I2C_IF_TXC ) {
1639+ sl_hal_i2c_disable_interrupts (i2c_base_addr , I2C_IEN_TXC );
1640+ sl_hal_i2c_clear_interrupts (i2c_base_addr , I2C_IF_TXC );
1641+ DMADRV_StopTransfer (sl_i2c_instance -> dma_channel .dma_tx_channel );
1642+ (i2c_base_addr )-> CTRL = _I2C_CTRL_RESETVALUE ;
1643+ if (sl_i2c_instance -> rstart == RSTART_WRITE_INPROGRESS ) {
1644+ sl_i2c_instance -> transfer_seq = SL_I2C_READ ;
1645+ sl_i2c_instance -> transfer_mode = SLI_I2C_NON_BLOCKING_TRANSFER ;
1646+ sl_i2c_instance -> transfer_event = SL_I2C_EVENT_IDLE ;
1647+ sl_i2c_instance -> addr_buffer [0 ] = 0 ;
1648+ sl_i2c_instance -> state = SLI_I2C_STATE_ADDR_WAIT_FOR_ACK_OR_NACK ;
1649+ sl_i2c_instance -> rstart = RSTART_READ_INPROGRESS ;
1650+ memset (sl_i2c_instance -> tx_desc , 0 , sizeof (sl_i2c_instance -> tx_desc ));
1651+ sli_i2c_dma_transfer_init (sl_i2c_instance );
1652+ }
16001653 } else if (pending_irq & I2C_IF_NACK ) {
16011654 sl_hal_i2c_clear_interrupts (i2c_base_addr , I2C_IF_NACK );
16021655 switch (sl_i2c_instance -> state ) {
@@ -1618,6 +1671,9 @@ void sli_i2c_leader_dispatch_interrupt(sli_i2c_instance_t *sl_i2c_instance)
16181671 sl_hal_i2c_disable_interrupts (i2c_base_addr , I2C_IEN_ACK );
16191672 sl_i2c_instance -> transfer_event = SL_I2C_EVENT_IN_PROGRESS ;
16201673 }
1674+ if (sl_i2c_instance -> rstart == RSTART_WRITE_INPROGRESS ) {
1675+ sl_hal_i2c_enable_interrupts (i2c_base_addr , I2C_IEN_TXC );
1676+ }
16211677 break ;
16221678
16231679 case SLI_I2C_STATE_ADDR_2ND_BYTE_10BIT_WAIT_FOR_ACK_OR_NACK :
0 commit comments