mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
450701f211
commit
57f4df64e5
|
@ -238,6 +238,23 @@ void i2c_hw_reset(i2c_t *obj) {
|
||||||
#endif
|
#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) {
|
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
||||||
|
|
||||||
struct i2c_s *obj_s = I2C_S(obj);
|
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 */
|
* to know when we need to prepare next start */
|
||||||
handle->Instance->CR2 &= ~I2C_CR2_SADD;
|
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)
|
/* 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) {
|
if (obj_s->XferOperation != I2C_FIRST_AND_LAST_FRAME) {
|
||||||
i2c_init(obj, obj_s->sda, obj_s->scl);
|
i2c_init(obj, obj_s->sda, obj_s->scl);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue