Skip to content

Commit d9676cc

Browse files
author
Jamie Smith
authored
Fix STM32 I2C v2 async transfer not doing a repeated start (#197)
* Fix STM32 I2C v2 async transfer not doing a repeated start * Clarify docs
1 parent 28815b1 commit d9676cc

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

drivers/include/drivers/I2C.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ class I2C : private NonCopyable<I2C> {
377377
*
378378
* The %I2C peripheral will begin a transmit and/or receive operation in the background. If only a transmit
379379
* or receive buffer is specified, only a transmit or receive will be done. If both buffers are specified,
380-
* first the transmission is done to the given slave address, then the specified number of bytes are received.
380+
* first the transmission is done to the given slave address, then the MCU performs a repeated start
381+
* and the specified number of bytes are received.
381382
*
382383
* If you wish to find out when the transfer is done, pass a callback function to the callback argument
383384
* and set the event argument to the events you wish to receive.
@@ -400,7 +401,7 @@ class I2C : private NonCopyable<I2C> {
400401
* of the flags I2C_EVENT_ERROR, I2C_EVENT_ERROR_NO_SLAVE, I2C_EVENT_TRANSFER_COMPLETE, or I2C_EVENT_TRANSFER_EARLY_NACK
401402
* @param callback The event callback function
402403
* @param repeated Set up for a repeated start. If true, the Mbed processor does not relinquish the bus after
403-
* this write operation. You may then call write(), read(), or start() again to start another operation.
404+
* this operation. You may then call write(), read(), start(), or transfer() again to start another operation.
404405
*
405406
* @returns Zero if the transfer has started, or -1 if I2C peripheral is busy
406407
*/
@@ -415,7 +416,8 @@ class I2C : private NonCopyable<I2C> {
415416
*
416417
* The %I2C peripheral will begin a transmit and/or receive operation in the background. If only a transmit
417418
* or receive buffer is specified, only a transmit or receive will be done. If both buffers are specified,
418-
* first the transmission is done to the given slave address, then the specified number of bytes are received.
419+
* first the transmission is done to the given slave address, then the MCU performs a repeated start
420+
* and the specified number of bytes are received.
419421
*
420422
* Internally, the chip vendor may implement this function using either DMA or interrupts.
421423
*
@@ -428,7 +430,7 @@ class I2C : private NonCopyable<I2C> {
428430
* @param rx_length The length of RX buffer in bytes If 0, no reception is done.
429431
* @param timeout timeout value. Use #rtos::Kernel::wait_for_u32_forever to wait forever (the default).
430432
* @param repeated Set up for a repeated start. If true, the Mbed processor does not relinquish the bus after
431-
* this operation. You may then call write(), read(), or start() again to start another operation.
433+
* this operation. You may then call write(), read(), start(), or transfer() again to start another operation.
432434
*
433435
* @returns Result code describing whether the transfer succeeded or not.
434436
*/

targets/TARGET_STM/i2c_api.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,7 @@ void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
13891389
if(obj->rx_buff.length > 0)
13901390
{
13911391
// This is a write-then-read transaction, switch to reading.
1392-
uint32_t xferOptions = obj_s->stop ? I2C_FIRST_AND_LAST_FRAME : I2C_FIRST_FRAME;
1392+
uint32_t xferOptions = get_hal_xfer_options(obj_s, obj_s->stop);
13931393
HAL_I2C_Master_Seq_Receive_IT(hi2c, obj_s->address, (uint8_t *) obj->rx_buff.buffer, obj->rx_buff.length,
13941394
xferOptions);
13951395
obj_s->state = STM_I2C_ASYNC_READ_IN_PROGRESS;
@@ -1784,7 +1784,11 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
17841784

17851785
prep_for_restart_if_needed(obj_s);
17861786

1787-
uint32_t xferOptions = get_hal_xfer_options(obj_s, stop);
1787+
// If we are doing both a tx and an rx, then we never want to send a stop on the
1788+
// first transfer.
1789+
bool sendStopOnFirstTransfer = stop && ((tx_length == 0) || (rx_length == 0));
1790+
1791+
uint32_t xferOptions = get_hal_xfer_options(obj_s, sendStopOnFirstTransfer);
17881792

17891793
if(!i2c_is_ready_for_transaction_start(obj_s->state))
17901794
{

0 commit comments

Comments
 (0)