STM32: I2C: reset state machine

this I2C IP is meant for automatic STOP, based on programmed number
of bytes to be sent or receivede, not a user triggered STOP.
So the state machiine needs to be reset in case we use this I2C mbed
unitary API (start / byte_write / byte_read / stop).
pull/3685/head
Laurent MEUNIER 2017-02-02 14:36:15 +01:00
parent 450701f211
commit 57f4df64e5
1 changed files with 24 additions and 1 deletions

View File

@ -238,6 +238,23 @@ void i2c_hw_reset(i2c_t *obj) {
#endif
}
void i2c_sw_reset(i2c_t *obj)
{
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
/* SW reset procedure:
* PE must be kept low during at least 3 APB clock cycles
* in order to perform the software reset.
* This is ensured by writing the following software sequence:
* - Write PE=0
* - Check PE=0
* - Write PE=1.
*/
handle->Instance->CR1 &= ~I2C_CR1_PE;
while(handle->Instance->CR1 & I2C_CR1_PE);
handle->Instance->CR1 |= I2C_CR1_PE;
}
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
struct i2c_s *obj_s = I2C_S(obj);
@ -597,8 +614,14 @@ int i2c_stop(i2c_t *obj) {
* to know when we need to prepare next start */
handle->Instance->CR2 &= ~I2C_CR2_SADD;
/*
* V2 IP is meant for automatic STOP, not user STOP
* SW reset the IP state machine before next transaction
*/
i2c_sw_reset(obj);
/* In case of mixed usage of the APIs (unitary + SYNC)
* re-inti HAL state */
* re-init HAL state */
if (obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME) {
i2c_init(obj, obj_s->sda, obj_s->scl);
}