Skip to content

Commit 0e04161

Browse files
authored
Merge pull request #3685 from LMESTM/fix_i2c_sw_reset
STM32: I2C: reset state machine
2 parents ea7f15f + 57f4df6 commit 0e04161

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

targets/TARGET_STM/i2c_api.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,23 @@ void i2c_hw_reset(i2c_t *obj) {
238238
#endif
239239
}
240240

241+
void i2c_sw_reset(i2c_t *obj)
242+
{
243+
struct i2c_s *obj_s = I2C_S(obj);
244+
I2C_HandleTypeDef *handle = &(obj_s->handle);
245+
/* SW reset procedure:
246+
* PE must be kept low during at least 3 APB clock cycles
247+
* in order to perform the software reset.
248+
* This is ensured by writing the following software sequence:
249+
* - Write PE=0
250+
* - Check PE=0
251+
* - Write PE=1.
252+
*/
253+
handle->Instance->CR1 &= ~I2C_CR1_PE;
254+
while(handle->Instance->CR1 & I2C_CR1_PE);
255+
handle->Instance->CR1 |= I2C_CR1_PE;
256+
}
257+
241258
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
242259

243260
struct i2c_s *obj_s = I2C_S(obj);
@@ -595,8 +612,14 @@ int i2c_stop(i2c_t *obj) {
595612
* to know when we need to prepare next start */
596613
handle->Instance->CR2 &= ~I2C_CR2_SADD;
597614

615+
/*
616+
* V2 IP is meant for automatic STOP, not user STOP
617+
* SW reset the IP state machine before next transaction
618+
*/
619+
i2c_sw_reset(obj);
620+
598621
/* In case of mixed usage of the APIs (unitary + SYNC)
599-
* re-inti HAL state */
622+
* re-init HAL state */
600623
if (obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME) {
601624
i2c_init(obj, obj_s->sda, obj_s->scl);
602625
}

0 commit comments

Comments
 (0)