STM: I2C: Confifure pins in OpenDrainNoPull by default (no pullup)

As reported by MBED user Fran6Jack:
I2C bus are usually 5V tolerant on all STM32 processor.
If an external device on the I2C bus requires 5V operation,
we usually acheive it by using 5V external pull-ups on the bus.
Since signaling uses open-drain output on I2C for both signal SCL and SDA
any 5V tolerant MCU will work on a 5V I2C bus. Having pull-up activated on a 5V externally pull bus, cause the pin to clamp on the STM32 die diode and could damage the IC (There is a note in STM32 datasheet specifying this issue).
It is understood by all the community that I2C bus should always be
externally pulled by physical resistor. I2C initialization should then
be ALWAYS OpenDrainNoPull by default.

Up to now, this I2C driver was setting pull up by default as it helps
basic testing, like 1 master and 1 slave, conencted with 2 wires without
any external pull ups. This will not work anymore after this commit and
applications tests or examples needs to be modified to explicitely
configure pull ups ...  But it is safer to follow reference manual
guidelines.
pull/5113/head
Laurent MEUNIER 2017-09-14 17:15:11 +02:00
parent 5bddd881e9
commit 076b096efe
1 changed files with 6 additions and 24 deletions

View File

@ -274,10 +274,6 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
obj_s->index = 0; obj_s->index = 0;
__HAL_RCC_I2C1_CLK_ENABLE(); __HAL_RCC_I2C1_CLK_ENABLE();
// Configure I2C pins // Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrainPullUp);
pin_mode(scl, OpenDrainPullUp);
obj_s->event_i2cIRQ = I2C1_EV_IRQn; obj_s->event_i2cIRQ = I2C1_EV_IRQn;
obj_s->error_i2cIRQ = I2C1_ER_IRQn; obj_s->error_i2cIRQ = I2C1_ER_IRQn;
} }
@ -287,11 +283,6 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
if (obj_s->i2c == I2C_2) { if (obj_s->i2c == I2C_2) {
obj_s->index = 1; obj_s->index = 1;
__HAL_RCC_I2C2_CLK_ENABLE(); __HAL_RCC_I2C2_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrainPullUp);
pin_mode(scl, OpenDrainPullUp);
obj_s->event_i2cIRQ = I2C2_EV_IRQn; obj_s->event_i2cIRQ = I2C2_EV_IRQn;
obj_s->error_i2cIRQ = I2C2_ER_IRQn; obj_s->error_i2cIRQ = I2C2_ER_IRQn;
} }
@ -301,11 +292,6 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
if (obj_s->i2c == I2C_3) { if (obj_s->i2c == I2C_3) {
obj_s->index = 2; obj_s->index = 2;
__HAL_RCC_I2C3_CLK_ENABLE(); __HAL_RCC_I2C3_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrainPullUp);
pin_mode(scl, OpenDrainPullUp);
obj_s->event_i2cIRQ = I2C3_EV_IRQn; obj_s->event_i2cIRQ = I2C3_EV_IRQn;
obj_s->error_i2cIRQ = I2C3_ER_IRQn; obj_s->error_i2cIRQ = I2C3_ER_IRQn;
} }
@ -315,11 +301,6 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
if (obj_s->i2c == I2C_4) { if (obj_s->i2c == I2C_4) {
obj_s->index = 3; obj_s->index = 3;
__HAL_RCC_I2C4_CLK_ENABLE(); __HAL_RCC_I2C4_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrainPullUp);
pin_mode(scl, OpenDrainPullUp);
obj_s->event_i2cIRQ = I2C4_EV_IRQn; obj_s->event_i2cIRQ = I2C4_EV_IRQn;
obj_s->error_i2cIRQ = I2C4_ER_IRQn; obj_s->error_i2cIRQ = I2C4_ER_IRQn;
} }
@ -329,16 +310,17 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
if (obj_s->i2c == FMPI2C_1) { if (obj_s->i2c == FMPI2C_1) {
obj_s->index = 4; obj_s->index = 4;
__HAL_RCC_FMPI2C1_CLK_ENABLE(); __HAL_RCC_FMPI2C1_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrainPullUp);
pin_mode(scl, OpenDrainPullUp);
obj_s->event_i2cIRQ = FMPI2C1_EV_IRQn; obj_s->event_i2cIRQ = FMPI2C1_EV_IRQn;
obj_s->error_i2cIRQ = FMPI2C1_ER_IRQn; obj_s->error_i2cIRQ = FMPI2C1_ER_IRQn;
} }
#endif #endif
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrainNoPull);
pin_mode(scl, OpenDrainNoPull);
// I2C configuration // I2C configuration
// Default hz value used for timeout computation // Default hz value used for timeout computation
if(!obj_s->hz) if(!obj_s->hz)