STM32F091 I2C1 not working but I2C2 works perfectly.
I have a design where I am using both I2C1 (external ADC) and I2C2 (external EEPROM). I have no problem making I2C2 work perfectly. The MCU both transmits and receives messages with no problem and I can see in on the Oscilloscope. However, when I attempt to use I2C1 in the same way, using the same HAL commands:
HAL_I2C_Master_Transmit(&hi2c1, ADCAddrWrite, ADCConfigCond, 0x01, 1000);
and
HAL_I2C_Master_Receive(&hi2c1, ADCAddrRead, (uint8_t *)aRxBuffer, 0x02, 1000);
It does not work. On the oscilloscope I can see the clock signal go low briefly and then go high again every time the MCU attempts to either send or receive a message. I think the MCU is issuing the Start bit but then it times out. When I use the debugger and follow the code through step by step I see that the bus is timing out (or at least I think it is). If I elongate the timeout to 10 seconds I can even count it off and see that the MCU pauses at the command for 10 seconds and then moves on. If it was a bad ADC chip I would expect the Transmit to work perfectly but the receive command to timeout and not work, but that's not what's happening.
For the record I used STMCubeMX to generate my code (other than the application specific code I've added since) and I have my HAL libraries up to date. I know in the past the HAL libraries for I2C weren't great but it seems like things have changed/improved some since.
Is there something special about I2C1 vs. the other I2C buses that maybe I am not handling properly? I know it's clocked differently, but I have checked the clock initialization code and that seems to be correct. I've even switched it to run from the HSI and that didn't help. Here is the relevant code:
Initialization Code:
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x20303E5D;
// hi2c1.Init.Timing = 0x2000090D;
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_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/**Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/**Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
Pin Initialization code:
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
else if(hi2c->Instance==I2C2)
{
/* USER CODE BEGIN I2C2_MspInit 0 */
/* USER CODE END I2C2_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C2 GPIO Configuration
PB13 ------> I2C2_SCL
PB14 ------> I2C2_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_I2C2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C2_CLK_ENABLE();
/* USER CODE BEGIN I2C2_MspInit 1 */
/* USER CODE END I2C2_MspInit 1 */
}
}
I2C Transmit and Receive Commands:
HAL_I2C_Master_Transmit(&hi2c1, ADCAddrWrite, ADCConfigCond, 0x01, 1000);
HAL_Delay(100);
HAL_I2C_Master_Receive(&hi2c1, ADCAddrRead, (uint8_t *)aRxBuffer, 0x02, 1000);
HAL_Delay(100);