Skip to content

I2 c sequential communication rework #11334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2592,7 +2592,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If size > MAX_NBYTE_SIZE, use reload mode */
Expand Down Expand Up @@ -2658,7 +2658,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
Expand Down
4 changes: 2 additions & 2 deletions targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2592,7 +2592,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED patch
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If size > MAX_NBYTE_SIZE, use reload mode */
Expand Down Expand Up @@ -2666,7 +2666,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED patch
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
Expand Down
4 changes: 2 additions & 2 deletions targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2598,7 +2598,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED: changed
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If size > MAX_NBYTE_SIZE, use reload mode */
Expand Down Expand Up @@ -2672,7 +2672,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED: changed
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
Expand Down
4 changes: 2 additions & 2 deletions targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2592,7 +2592,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED commit 23926a2418
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If size > MAX_NBYTE_SIZE, use reload mode */
Expand Down Expand Up @@ -2666,7 +2666,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED commit 23926a2418
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
Expand Down
6 changes: 2 additions & 4 deletions targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -3173,8 +3173,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
// Added for MBED PR #3324
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
Expand Down Expand Up @@ -3420,8 +3419,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
// Added for MBED PR #3324
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferOptions = XferOptions;
hi2c->XferISR = I2C_Master_ISR_IT;

/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
Expand Down
76 changes: 63 additions & 13 deletions targets/TARGET_STM/i2c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "pinmap.h"
#include "PeripheralPins.h"
#include "i2c_device.h" // family specific defines
#include "mbed_error.h"

#ifndef DEBUG_STDIO
# define DEBUG_STDIO 0
Expand Down Expand Up @@ -597,8 +598,6 @@ int i2c_stop(i2c_t *obj)
return 0;
}
#endif
// Disable reload mode
handle->Instance->CR2 &= (uint32_t)~I2C_CR2_RELOAD;

// Ensure the transmission is started before sending a stop
if ((handle->Instance->CR2 & (uint32_t)I2C_CR2_RD_WRN) == 0) {
Expand All @@ -611,7 +610,7 @@ int i2c_stop(i2c_t *obj)
}

// Generate the STOP condition
handle->Instance->CR2 |= I2C_CR2_STOP;
handle->Instance->CR2 = I2C_CR2_STOP;

timeout = FLAG_TIMEOUT;
while (!__HAL_I2C_GET_FLAG(handle, I2C_FLAG_STOPF)) {
Expand Down Expand Up @@ -664,9 +663,16 @@ int i2c_byte_read(i2c_t *obj, int last)
}
}

/* Enable reload mode as we don't know how many bytes will be sent */
/* and set transfer size to 1 */
tmpreg |= I2C_CR2_RELOAD | (I2C_CR2_NBYTES & (1 << 16));
if (last) {
/* Disable Address Acknowledge */
tmpreg = tmpreg & (~I2C_CR2_RELOAD);
tmpreg |= I2C_CR2_NACK | (I2C_CR2_NBYTES & (1 << 16));
} else {
/* Enable reload mode as we don't know how many bytes will be sent */
/* and set transfer size to 1 */
tmpreg |= I2C_CR2_RELOAD | (I2C_CR2_NBYTES & (1 << 16));
}

/* Set the prepared configuration */
handle->Instance->CR2 = tmpreg;

Expand All @@ -680,11 +686,6 @@ int i2c_byte_read(i2c_t *obj, int last)
/* Then Get Byte */
data = handle->Instance->RXDR;

if (last) {
/* Disable Address Acknowledge */
handle->Instance->CR2 |= I2C_CR2_NACK;
}

return data;
}

Expand Down Expand Up @@ -760,7 +761,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
I2C_HandleTypeDef *handle = &(obj_s->handle);
int count = I2C_ERROR_BUS_BUSY, ret = 0;
uint32_t timeout = 0;

#if defined(I2C_IP_VERSION_V1)
// Trick to remove compiler warning "left and right operands are identical" in some cases
uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
uint32_t op2 = I2C_LAST_FRAME;
Expand All @@ -778,6 +779,18 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
obj_s->XferOperation = I2C_NEXT_FRAME;
}
}
#elif defined(I2C_IP_VERSION_V2)
if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) {
if (stop) {
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
} else {
obj_s->XferOperation = I2C_FIRST_FRAME;
}
} else {
// should not happend
error("I2C: abnormal case should not happend");
}
#endif

obj_s->event = 0;

Expand Down Expand Up @@ -818,6 +831,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
int count = I2C_ERROR_BUS_BUSY, ret = 0;
uint32_t timeout = 0;

#if defined(I2C_IP_VERSION_V1)
// Trick to remove compiler warning "left and right operands are identical" in some cases
uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
uint32_t op2 = I2C_LAST_FRAME;
Expand All @@ -835,6 +849,18 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
obj_s->XferOperation = I2C_NEXT_FRAME;
}
}
#elif defined(I2C_IP_VERSION_V2)
if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) {
if (stop) {
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
} else {
obj_s->XferOperation = I2C_FIRST_FRAME;
}
} else {
// should not happend
error("I2C: abnormal case should not happend");
}
#endif

obj_s->event = 0;

Expand Down Expand Up @@ -874,11 +900,19 @@ void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
#if DEVICE_I2C_ASYNCH
/* Handle potential Tx/Rx use case */
if ((obj->tx_buff.length) && (obj->rx_buff.length)) {
#if defined(I2C_IP_VERSION_V1)
if (obj_s->stop) {
obj_s->XferOperation = I2C_LAST_FRAME;
} else {
obj_s->XferOperation = I2C_NEXT_FRAME;
}
#elif defined(I2C_IP_VERSION_V2)
if (obj_s->stop) {
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
} else {
obj_s->XferOperation = I2C_FIRST_FRAME;
}
#endif

HAL_I2C_Master_Sequential_Receive_IT(hi2c, obj_s->address, (uint8_t *)obj->rx_buff.buffer, obj->rx_buff.length, obj_s->XferOperation);
} else
Expand Down Expand Up @@ -1143,6 +1177,7 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,

/* Set operation step depending if stop sending required or not */
if ((tx_length && !rx_length) || (!tx_length && rx_length)) {
#if defined(I2C_IP_VERSION_V1)
// Trick to remove compiler warning "left and right operands are identical" in some cases
uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
uint32_t op2 = I2C_LAST_FRAME;
Expand All @@ -1160,7 +1195,18 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
obj_s->XferOperation = I2C_NEXT_FRAME;
}
}

#elif defined(I2C_IP_VERSION_V2)
if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) {
if (stop) {
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
} else {
obj_s->XferOperation = I2C_FIRST_FRAME;
}
} else {
// should not happend
error("I2C: abnormal case should not happend");
}
#endif
if (tx_length > 0) {
HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, obj_s->XferOperation);
}
Expand All @@ -1169,6 +1215,7 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
}
} else if (tx_length && rx_length) {
/* Two steps operation, don't modify XferOperation, keep it for next step */
#if defined(I2C_IP_VERSION_V1)
// Trick to remove compiler warning "left and right operands are identical" in some cases
uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
uint32_t op2 = I2C_LAST_FRAME;
Expand All @@ -1178,6 +1225,9 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
(obj_s->XferOperation == I2C_NEXT_FRAME)) {
HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, I2C_NEXT_FRAME);
}
#elif defined(I2C_IP_VERSION_V2)
HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, I2C_FIRST_FRAME);
#endif
}
}

Expand Down