Skip to content

Commit 5d62f96

Browse files
AlessandroLuokartben
authored andcommitted
drivers: i2c: ambiq: Optimized i2c_ambiq_transfer to handle frame header
Need to send the device address together with data in one transaction, instead of splitting into two. Signed-off-by: Hao Luo <[email protected]>
1 parent 192b780 commit 5d62f96

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

drivers/i2c/i2c_ambiq.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ static void i2c_ambiq_isr(const struct device *dev)
166166
k_sem_give(&data->transfer_sem);
167167
}
168168

169-
static int i2c_ambiq_read(const struct device *dev, struct i2c_msg *msg, uint16_t addr)
169+
static int i2c_ambiq_read(const struct device *dev, struct i2c_msg *hdr_msg,
170+
struct i2c_msg *data_msg, uint16_t addr)
170171
{
171172
struct i2c_ambiq_data *data = dev->data;
172173

@@ -177,8 +178,19 @@ static int i2c_ambiq_read(const struct device *dev, struct i2c_msg *msg, uint16_
177178
trans.ui8Priority = 1;
178179
trans.eDirection = AM_HAL_IOM_RX;
179180
trans.uPeerInfo.ui32I2CDevAddr = addr;
180-
trans.ui32NumBytes = msg->len;
181-
trans.pui32RxBuffer = (uint32_t *)msg->buf;
181+
trans.ui32NumBytes = data_msg->len;
182+
trans.pui32RxBuffer = (uint32_t *)data_msg->buf;
183+
if (hdr_msg) {
184+
if (hdr_msg->len > AM_HAL_IOM_MAX_OFFSETSIZE) {
185+
return -E2BIG;
186+
}
187+
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
188+
trans.ui32Instr = (*(uint32_t *)hdr_msg->buf) & (0xFFFFFFFF >> (32 - (hdr_msg->len * 8)));
189+
#else
190+
trans.ui64Instr = (*(uint64_t *)hdr_msg->buf) & (0xFFFFFFFFFFFFFFFF >> (64 - (hdr_msg->len * 8)));
191+
#endif
192+
trans.ui32InstrLen = hdr_msg->len;
193+
}
182194

183195
#ifdef CONFIG_I2C_AMBIQ_DMA
184196
data->transfer_status = -EFAULT;
@@ -204,7 +216,8 @@ static int i2c_ambiq_read(const struct device *dev, struct i2c_msg *msg, uint16_
204216
return (ret != AM_HAL_STATUS_SUCCESS) ? -EIO : 0;
205217
}
206218

207-
static int i2c_ambiq_write(const struct device *dev, struct i2c_msg *msg, uint16_t addr)
219+
static int i2c_ambiq_write(const struct device *dev, struct i2c_msg *hdr_msg,
220+
struct i2c_msg *data_msg, uint16_t addr)
208221
{
209222
struct i2c_ambiq_data *data = dev->data;
210223

@@ -215,8 +228,19 @@ static int i2c_ambiq_write(const struct device *dev, struct i2c_msg *msg, uint16
215228
trans.ui8Priority = 1;
216229
trans.eDirection = AM_HAL_IOM_TX;
217230
trans.uPeerInfo.ui32I2CDevAddr = addr;
218-
trans.ui32NumBytes = msg->len;
219-
trans.pui32TxBuffer = (uint32_t *)msg->buf;
231+
trans.ui32NumBytes = data_msg->len;
232+
trans.pui32TxBuffer = (uint32_t *)data_msg->buf;
233+
if (hdr_msg) {
234+
if (hdr_msg->len > AM_HAL_IOM_MAX_OFFSETSIZE) {
235+
return -E2BIG;
236+
}
237+
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
238+
trans.ui32Instr = (*(uint32_t *)hdr_msg->buf) & (0xFFFFFFFF >> (32 - (hdr_msg->len * 8)));
239+
#else
240+
trans.ui64Instr = (*(uint64_t *)hdr_msg->buf) & (0xFFFFFFFFFFFFFFFF >> (64 - (hdr_msg->len * 8)));
241+
#endif
242+
trans.ui32InstrLen = hdr_msg->len;
243+
}
220244

221245
#ifdef CONFIG_I2C_AMBIQ_DMA
222246
data->transfer_status = -EFAULT;
@@ -301,9 +325,16 @@ static int i2c_ambiq_transfer(const struct device *dev, struct i2c_msg *msgs, ui
301325

302326
for (int i = 0; i < num_msgs; i++) {
303327
if (msgs[i].flags & I2C_MSG_READ) {
304-
ret = i2c_ambiq_read(dev, &(msgs[i]), addr);
328+
ret = i2c_ambiq_read(dev, NULL, &(msgs[i]), addr);
329+
} else if ((i + 1) < num_msgs) {
330+
if (msgs[i + 1].flags & I2C_MSG_READ) {
331+
ret = i2c_ambiq_read(dev, &(msgs[i]), &(msgs[i + 1]), addr);
332+
} else {
333+
ret = i2c_ambiq_write(dev, &(msgs[i]), &(msgs[i + 1]), addr);
334+
}
335+
i++;
305336
} else {
306-
ret = i2c_ambiq_write(dev, &(msgs[i]), addr);
337+
ret = i2c_ambiq_write(dev, NULL, &(msgs[i]), addr);
307338
}
308339

309340
if (ret != 0) {

0 commit comments

Comments
 (0)