The TransmitBlocking() times out, in the following code in HAL_I2C_Master_Transmit()
/* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
/* Wait until STOPF flag is set */
if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
return HAL_ERROR;
}
Internal pull-up resistors in MCUs are typically for GPIO configured as an input, but I2C pins are meant to be bidirectional and configured as open-drain, which means they require external pull-up resistors. This is a standard requirement of an I2C circuit and I don’t believe you’ll be able to get around it by enabling internal pullups. They’ll simply be unused/disabled for open-drain pin configuration when using the pins for I2C. EDIT: this is incorrect, see below.
My apologies, you are correct - according to the reference manual the open-drain GPIO modes can indeed work in tandem with pull-up/down resistors. However, libDaisy’s I2CHandle is hard coded to initialize the pins without any internal pull-ups, as you’ve discovered and changed.
I suppose the biggest difference is resistor value. The STM32H750 datasheet lists the weak pull-up resistor equivalent values as being anywhere from 30-50k Ohm (40k Ohm typical) which is an order of magnitude too large for most I2C circuits – 4.7k Ohm is often thrown out as a “safe” value for typical parasitic capacitance in short trace circuits running at ~100kHz. And the resistors will need to be even smaller for higher frequencies to meet the edge rise/fall time requirements.
I did some more testing and at 100Khz, even though it seemed to be working (as in the data seemed to be correct) the time taken was about 80% longer, so I looked on the analyser and acks were missing, there must be some kind of retry going on in the HAL.
At 400Khz it was totally dead.
So I guess we are both correct here
I will check more at 400Khz, maybe there are also retries there as I am using only 4.7K resistors.