In the code generated by KDS 3.0.0 for I2C initialization there is no call to PORT_HAL_SetOpenDrainCmd. As a result the I2C pins end up in push/pull mode which is against the I2C spec and causes no end of problems with devices that are not strong enough to overcome weak pull-up on Kinetis devices (an example would be Toshiba TC358765 DSI to LVDS chip). Am I missing something here?
Here is the code generated by KDS 2.0.0 (in the pin_mux.c)
void pin_mux_I2C(uint32_t instance)
{
switch(instance) {
case 0: /* I2C0 */
/* PORTB_PCR2 */
PORT_HAL_SetMuxMode(PORTB_BASE,0u,kPortMuxAlt2);
PORT_HAL_SetOpenDrainCmd(PORTB_BASE,0u,true);
/* PORTB_PCR3 */
PORT_HAL_SetMuxMode(PORTB_BASE,1u,kPortMuxAlt2);
PORT_HAL_SetOpenDrainCmd(PORTB_BASE,1u,true);
break;
case 1: /* I2C1 */
/* PORTC_PCR10 */
PORT_HAL_SetMuxMode(PORTE_BASE,0u,kPortMuxAlt6);
PORT_HAL_SetOpenDrainCmd(PORTE_BASE,0u,true);
/* PORTC_PCR11 */
PORT_HAL_SetMuxMode(PORTE_BASE,1u,kPortMuxAlt6);
PORT_HAL_SetOpenDrainCmd(PORTE_BASE,1u,true);
break;
default:
break;
}
}
And here is what I get with KDS 3.0.0:
void init_i2c_pins(uint32_t instance)
{
switch(instance) {
case I2C0_IDX: /* I2C0_IDX */
/* Affects PORTB_PCR0 register */
PORT_HAL_SetMuxMode(PORTB,0UL,kPortMuxAlt2);
/* Affects PORTB_PCR1 register */
PORT_HAL_SetMuxMode(PORTB,1UL,kPortMuxAlt2);
break;
case I2C1_IDX: /* I2C1_IDX */
/* Affects PORTE_PCR1 register */
PORT_HAL_SetMuxMode(PORTE,1UL,kPortMuxAlt6);
/* Affects PORTE_PCR0 register */
PORT_HAL_SetMuxMode(PORTE,0UL,kPortMuxAlt6);
break;
default:
break;
}
}
Quite obviously, the latter is wrong. From the I2C specification:
"The output stages of devices connected to the bus
must have an open-drain or open-collector to perform the
wired-AND function"