Skip to content

Commit 7910de2

Browse files
committed
TARGET_STM: Fix I2C sequential communication
Keep former behaviour for I2C V1. For I2C V2: Use only I2C_FIRST_FRAME, I2C_FIRST_AND_LAST_FRAME and I2C_LAST_FRAME, thus we avoid using reload bit. Reload suppose the next frame would be in the same direction, but we have no guarranty about this. So we cannot use reload bit. Note: in case of 2 consecutive I2C_FIRST_FRAME, a restart is automatically generated only if there is direction change in the direction.
1 parent 7647b39 commit 7910de2

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

targets/TARGET_STM/i2c_api.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "pinmap.h"
4141
#include "PeripheralPins.h"
4242
#include "i2c_device.h" // family specific defines
43+
#include "mbed_error.h"
4344

4445
#ifndef DEBUG_STDIO
4546
# define DEBUG_STDIO 0
@@ -760,7 +761,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
760761
I2C_HandleTypeDef *handle = &(obj_s->handle);
761762
int count = I2C_ERROR_BUS_BUSY, ret = 0;
762763
uint32_t timeout = 0;
763-
764+
#if defined(I2C_IP_VERSION_V1)
764765
// Trick to remove compiler warning "left and right operands are identical" in some cases
765766
uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
766767
uint32_t op2 = I2C_LAST_FRAME;
@@ -778,6 +779,18 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
778779
obj_s->XferOperation = I2C_NEXT_FRAME;
779780
}
780781
}
782+
#elif defined(I2C_IP_VERSION_V2)
783+
if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) {
784+
if (stop) {
785+
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
786+
} else {
787+
obj_s->XferOperation = I2C_FIRST_FRAME;
788+
}
789+
} else {
790+
// should not happend
791+
error("I2C: abnormal case should not happend");
792+
}
793+
#endif
781794

782795
obj_s->event = 0;
783796

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

834+
#if defined(I2C_IP_VERSION_V1)
821835
// Trick to remove compiler warning "left and right operands are identical" in some cases
822836
uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
823837
uint32_t op2 = I2C_LAST_FRAME;
@@ -835,6 +849,18 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
835849
obj_s->XferOperation = I2C_NEXT_FRAME;
836850
}
837851
}
852+
#elif defined(I2C_IP_VERSION_V2)
853+
if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) {
854+
if (stop) {
855+
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
856+
} else {
857+
obj_s->XferOperation = I2C_FIRST_FRAME;
858+
}
859+
} else {
860+
// should not happend
861+
error("I2C: abnormal case should not happend");
862+
}
863+
#endif
838864

839865
obj_s->event = 0;
840866

@@ -874,11 +900,19 @@ void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
874900
#if DEVICE_I2C_ASYNCH
875901
/* Handle potential Tx/Rx use case */
876902
if ((obj->tx_buff.length) && (obj->rx_buff.length)) {
903+
#if defined(I2C_IP_VERSION_V1)
877904
if (obj_s->stop) {
878905
obj_s->XferOperation = I2C_LAST_FRAME;
879906
} else {
880907
obj_s->XferOperation = I2C_NEXT_FRAME;
881908
}
909+
#elif defined(I2C_IP_VERSION_V2)
910+
if (obj_s->stop) {
911+
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
912+
} else {
913+
obj_s->XferOperation = I2C_FIRST_FRAME;
914+
}
915+
#endif
882916

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

11441178
/* Set operation step depending if stop sending required or not */
11451179
if ((tx_length && !rx_length) || (!tx_length && rx_length)) {
1180+
#if defined(I2C_IP_VERSION_V1)
11461181
// Trick to remove compiler warning "left and right operands are identical" in some cases
11471182
uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
11481183
uint32_t op2 = I2C_LAST_FRAME;
@@ -1160,7 +1195,18 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
11601195
obj_s->XferOperation = I2C_NEXT_FRAME;
11611196
}
11621197
}
1163-
1198+
#elif defined(I2C_IP_VERSION_V2)
1199+
if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) {
1200+
if (stop) {
1201+
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
1202+
} else {
1203+
obj_s->XferOperation = I2C_FIRST_FRAME;
1204+
}
1205+
} else {
1206+
// should not happend
1207+
error("I2C: abnormal case should not happend");
1208+
}
1209+
#endif
11641210
if (tx_length > 0) {
11651211
HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, obj_s->XferOperation);
11661212
}
@@ -1169,6 +1215,7 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
11691215
}
11701216
} else if (tx_length && rx_length) {
11711217
/* Two steps operation, don't modify XferOperation, keep it for next step */
1218+
#if defined(I2C_IP_VERSION_V1)
11721219
// Trick to remove compiler warning "left and right operands are identical" in some cases
11731220
uint32_t op1 = I2C_FIRST_AND_LAST_FRAME;
11741221
uint32_t op2 = I2C_LAST_FRAME;
@@ -1178,6 +1225,9 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
11781225
(obj_s->XferOperation == I2C_NEXT_FRAME)) {
11791226
HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, I2C_NEXT_FRAME);
11801227
}
1228+
#elif defined(I2C_IP_VERSION_V2)
1229+
HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, I2C_FIRST_FRAME);
1230+
#endif
11811231
}
11821232
}
11831233

0 commit comments

Comments
 (0)