I2C: Wrong Slave address on STM32H743ZI (Nucleo board)
This is more a bug report than an actual question.
I have experienced a wrong behavior of the I2C driver of STM32H743ZI MCU (Nucleo board).
What's happening? The driver is simply dividing by 2 the slave address passed as a parameter to the function HAL_I2C_Master_Transmit. This leads to an absence of communication between master and slave (which is here an aardvark I2C SPI adapter), since master is transmitting to an erroneous slave address.
The I2C handle is configured as follow:
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x10707DBC;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}And the main function calls:
transmitReturn = HAL_I2C_Master_Transmit ( &hi2c1, (uint16_t) I2C1_SLAVE_ADDRESS,uint8_t*) aI2C_TxBuffer, I2C2_TXBUFFERSIZE, 10000);Where I2C1_SLAVE_ADDRESS's value is 0x48 (bin: 1001000).
In the attached document scope_KO_I2C_slave_adr_0x48.bmp, you can see the transmitted slave address on the SDA that I captured with an oscilloscope. Instead of having bin1001000 as expected, we are reading bin0100100. This is actually the slave address shifted right, so it is divided by two.
Furthermore, I inspected the register where slave address is configured (I2C_CR2). The last byte of this register is dedicated to Slave address. As you can see in the attached register dump document register I2C.png , the correct slave address is written to the register (0x48). Somehow, the CPU divides this address by two afterward.
A simple correction for a developer is to multiply by two the desired slave address, before calling any HAL_I2C_*** function.
