84
84
|| (freq_mode == SL_I2C_FREQ_FAST_MODE) \
85
85
|| (freq_mode == SL_I2C_FREQ_FASTPLUS_MODE))
86
86
87
+ #define RSTART_WRITE_INPROGRESS 1
88
+ #define RSTART_READ_INPROGRESS 2
89
+
87
90
/*******************************************************************************
88
91
************************** LOCAL FUNCTIONS ********************************
89
92
******************************************************************************/
@@ -713,6 +716,38 @@ sl_status_t sl_i2c_receive_non_blocking(sl_i2c_handle_t i2c_handle,
713
716
return SL_STATUS_OK ;
714
717
}
715
718
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
+
716
751
/*******************************************************************************
717
752
************************** INTERNAL FUNCTIONS *****************************
718
753
******************************************************************************/
@@ -952,7 +987,9 @@ sl_status_t sli_i2c_dma_transfer_init(sli_i2c_instance_t *i2c_instance)
952
987
953
988
#if defined(EMDRV_DMADRV_LDMA )
954
989
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
+ }
956
993
i2c_instance -> tx_desc [0 ] = (LDMA_Descriptor_t )LDMA_DESCRIPTOR_LINKREL_M2P_BYTE ((void * )(addr_buffer ), & ((i2c_base_addr )-> TXDATA ), addr_buffer_count , 1 );
957
994
i2c_instance -> tx_desc [1 ] = (LDMA_Descriptor_t )LDMA_DESCRIPTOR_SINGLE_M2P_BYTE ((void * )data_buffer , & ((i2c_base_addr )-> TXDATA ), data_len );
958
995
} 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)
1590
1627
DMADRV_StopTransfer (sl_i2c_instance -> dma_channel .dma_tx_channel );
1591
1628
} else if (sl_i2c_instance -> transfer_seq == SL_I2C_READ ) {
1592
1629
DMADRV_StopTransfer (sl_i2c_instance -> dma_channel .dma_rx_channel );
1630
+ sl_i2c_instance -> rstart = 0 ;
1593
1631
}
1594
1632
1595
1633
(i2c_base_addr )-> CTRL = _I2C_CTRL_RESETVALUE ;
1596
1634
1597
1635
if (sl_i2c_instance -> transfer_event == SL_I2C_EVENT_IN_PROGRESS ) {
1598
1636
sl_i2c_instance -> transfer_event = SL_I2C_EVENT_COMPLETED ;
1599
1637
}
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
+ }
1600
1653
} else if (pending_irq & I2C_IF_NACK ) {
1601
1654
sl_hal_i2c_clear_interrupts (i2c_base_addr , I2C_IF_NACK );
1602
1655
switch (sl_i2c_instance -> state ) {
@@ -1618,6 +1671,9 @@ void sli_i2c_leader_dispatch_interrupt(sli_i2c_instance_t *sl_i2c_instance)
1618
1671
sl_hal_i2c_disable_interrupts (i2c_base_addr , I2C_IEN_ACK );
1619
1672
sl_i2c_instance -> transfer_event = SL_I2C_EVENT_IN_PROGRESS ;
1620
1673
}
1674
+ if (sl_i2c_instance -> rstart == RSTART_WRITE_INPROGRESS ) {
1675
+ sl_hal_i2c_enable_interrupts (i2c_base_addr , I2C_IEN_TXC );
1676
+ }
1621
1677
break ;
1622
1678
1623
1679
case SLI_I2C_STATE_ADDR_2ND_BYTE_10BIT_WAIT_FOR_ACK_OR_NACK :
0 commit comments