Skip to content

Commit ae1afd8

Browse files
fimohamejhedberg
authored andcommitted
simplicity_sdk: Patch to support combined transfer
added changes to support combined write read repeated start transfer for async operations Upstream-Status: Pending Signed-off-by: S Mohamed Fiaz <[email protected]>
1 parent 156d00d commit ae1afd8

File tree

3 files changed

+85
-2
lines changed

3 files changed

+85
-2
lines changed

simplicity_sdk/platform/driver/i2c/inc/sl_i2c.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,30 @@ sl_status_t sl_i2c_receive_non_blocking(sl_i2c_handle_t i2c_handle,
300300
uint16_t rx_len,
301301
sl_i2c_irq_callback_t i2c_callback,
302302
void *context);
303+
/***************************************************************************//**
304+
* Leader Mode : This function uses DMA and Interrupt, to perform a combined
305+
* write (tx_buffer) followed by a read (rx_buffer) from the follower configured
306+
* during Init API. A repeated START is generated between write and read without
307+
* issuing a STOP in between.
308+
* The user is notified through the provided callback function upon completion.
309+
*
310+
* @param[in] i2c_handle I2C Instance handle.
311+
* @param[in] tx_buffer A pointer to transmit data buffer.
312+
* @param[in] tx_len Transmit data length.
313+
* @param[out] rx_buffer A pointer to receive data buffer.
314+
* @param[in] rx_len Receive data length.
315+
* @param[in] i2c_callback A callback function on completion.
316+
* @param[in] context A pointer to user-defined data for callback.
317+
*
318+
* @return return status.
319+
******************************************************************************/
320+
sl_status_t sl_i2c_transfer_non_blocking(sl_i2c_handle_t i2c_handle,
321+
const uint8_t *tx_buffer,
322+
uint16_t tx_len,
323+
uint8_t *rx_buffer,
324+
uint16_t rx_len,
325+
sl_i2c_irq_callback_t i2c_callback,
326+
void *context);
303327

304328
/** @} (end addtogroup i2c driver) */
305329
#ifdef __cplusplus

simplicity_sdk/platform/driver/i2c/src/sl_i2c.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
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:

simplicity_sdk/platform/driver/i2c/src/sli_i2c.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ extern "C" {
4343
******************************* DEFINES ***********************************
4444
******************************************************************************/
4545
// Max number of descriptors for dma tx and rx operations.
46-
#define SL_I2C_DMA_MAX_TX_DESCRIPTOR_COUNT 2
46+
#define SL_I2C_DMA_MAX_TX_DESCRIPTOR_COUNT 5
4747
#define SL_I2C_DMA_MAX_RX_DESCRIPTOR_COUNT 5
4848

4949
/*******************************************************************************
@@ -116,6 +116,9 @@ typedef struct {
116116
uint8_t addr_buffer[3]; /// Address buffer.
117117
sl_i2c_irq_callback_t callback; /// I2C Callback.
118118
void *context; /// User-defined context.
119+
uint8_t addr_buffer_write[1]; /// Write address byte
120+
uint8_t addr_buffer_read[1]; /// Read address byte
121+
uint8_t rstart; /// Repeated Start.
119122
} sli_i2c_instance_t;
120123

121124
/***************************************************************************//**

0 commit comments

Comments
 (0)