I2C: don't block on reset
when resetting the GPIO lines are toggles. when this is not effective it used to block. not it just warns the used it failed.
This commit is contained in:
parent
396c7852e7
commit
ef4685a9a3
|
@ -252,34 +252,37 @@ bool i2c_master_check_signals(uint32_t i2c)
|
|||
return to_return;
|
||||
}
|
||||
|
||||
void i2c_master_reset(uint32_t i2c)
|
||||
bool i2c_master_reset(uint32_t i2c)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1!=i2c && I2C2!=i2c) {
|
||||
while (true);
|
||||
}
|
||||
|
||||
bool to_return = true;
|
||||
// follow procedure described in STM32F10xxC/D/E Errata sheet, Section 2.14.7
|
||||
i2c_peripheral_disable(i2c); // disable i2c peripheral
|
||||
gpio_set_mode(GPIO_PORT_SCL(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO_PIN_SCL(i2c)); // put I2C I/O pins to general output
|
||||
gpio_set(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // set high
|
||||
while (!gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c))); // ensure it is high
|
||||
to_return &= !gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // ensure it is high
|
||||
gpio_set_mode(GPIO_PORT_SDA(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO_PIN_SDA(i2c)); // put I2C I/O pins to general output
|
||||
gpio_set(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // set high
|
||||
while (!gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c))); // ensure it is high
|
||||
to_return &= !gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // ensure it is high
|
||||
gpio_clear(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // set low (try first transition)
|
||||
while (gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c))); // ensure it is low
|
||||
to_return &= gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // ensure it is low
|
||||
gpio_clear(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // set low (try first transition)
|
||||
while (gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c))); // ensure it is low
|
||||
to_return &= gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // ensure it is low
|
||||
gpio_set(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // set high (try second transition)
|
||||
while (!gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c))); // ensure it is high
|
||||
to_return &= !gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // ensure it is high
|
||||
gpio_set(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // set high (try second transition)
|
||||
while (!gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c))); // ensure it is high
|
||||
to_return &= !gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // ensure it is high
|
||||
gpio_set_mode(GPIO_PORT_SCL(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO_PIN_SCL(i2c)); // set I2C I/O pins back
|
||||
gpio_set_mode(GPIO_PORT_SDA(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO_PIN_SDA(i2c)); // set I2C I/O pins back
|
||||
I2C_CR1(i2c) |= I2C_CR1_SWRST; // reset device
|
||||
I2C_CR1(i2c) &= ~I2C_CR1_SWRST; // reset device
|
||||
i2c_peripheral_enable(i2c); // re-enable device
|
||||
|
||||
return to_return;
|
||||
}
|
||||
|
||||
enum i2c_master_rc i2c_master_start(uint32_t i2c)
|
||||
|
|
|
@ -46,8 +46,9 @@ void i2c_master_release(uint32_t i2c);
|
|||
* @warning the I2C peripheral needs to be re-setup
|
||||
* @note to be used after failed start or stop, and bus error
|
||||
* @param[in] i2c I2C base address
|
||||
* return true if complete reset is successful, false if the lines could not be set
|
||||
*/
|
||||
void i2c_master_reset(uint32_t i2c);
|
||||
bool i2c_master_reset(uint32_t i2c);
|
||||
/** check if SDA and SCL signals are high
|
||||
* @param[in] i2c I2C base address
|
||||
* @return SDA and SCL signals are high
|
||||
|
|
Loading…
Reference in New Issue