When i run the I2C scanner on STM32F303, i see both devices connected to the bus. Names a device on address 0x3C (OLED) and address (0x68) MPU6050. Both addresses, specifically agree with what the datasheet says.
However, when i try to read the WHO_AM_I register on address 0x68 using HAL_I2C_IsDeviceReady, i realize that it even times out.
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
MX_SPI1_Init();
MX_TIM6_Init();
MX_USART1_UART_Init();
I2C_Scanner();
SSD1306_Init();
HAL_Delay (2000);
MPU6050_Init();
while (1)
{
}
}
Function (MPU6050_Init) to check if the device is ready
static void MPU6050_Init(void)
{
HAL_Delay(1);
SSD1306_Clear();
SSD1306_GotoXY (0, 0);
char OutputArray[50] = {0};
if(HAL_I2C_IsDeviceReady(&hi2c1, MPU6050_I2C_ADDR, 10, HAL_MAX_DELAY) != HAL_OK)
{
sprintf(OutputArray, "0x%02x : Not ready", MPU6050_I2C_ADDR);
}
else
{
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
uint8_t check;
HAL_I2C_Mem_Read(&hi2c1, MPU6050_I2C_ADDR, WHO_AM_I_REG, 1, &check, 1, HAL_MAX_DELAY);
sprintf(OutputArray,"0x%02x", (uint16_t)check);
}
HAL_Delay(1);
SSD1306_Puts (OutputArray, &Font_7x10, SSD1306_COLOR_WHITE);
SSD1306_UpdateScreen();
}
Function (I2C_Scanner) to scan for I2C bus for available devices
static void I2C_Scanner(void)
{
HAL_StatusTypeDef result;
uint8_t i;
for (i = 1; i < 128; i++)
{
result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i << 1), 1, HAL_MAX_DELAY);
char* period = ".";
char OutputArray[5];
if (result != HAL_OK) // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT
{
HAL_UART_Transmit(&huart1, (uint8_t*)period, sizeof(period), HAL_MAX_DELAY);
}
if (result == HAL_OK)
{
sprintf(OutputArray, "0x%02x", i); // Received an ACK at that address
HAL_UART_Transmit(&huart1, (uint8_t*)OutputArray, sizeof(OutputArray), HAL_MAX_DELAY);
}
HAL_Delay(1);
}
}
Function (MC_I2C1_Init) to initialize the I2C
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x0000020B;
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();
}
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
}
The expected results would be to check that the device is available, ready and convey back the contents of the WHO_AM_I register
Found a solution. The problem was that i had defined the MPU6050 address as follows
#define MPU6050_I2C_ADDR 0x68
The correct definition should have been
#define MPU6050_I2C_ADDR 0x68 << 1
Which resulted in 0xD0