I2C read from device with STM32F767
Heelo friends.
I have STM32F767. And need to read from I2C device.
I2C device has address 0x4C. Speed is set to 100kHz.
This is my INIT I2C peripheral:
uint8_t I2C1_Init(void)
{
// declare and initialize pins to be used for I2C
LL_AHB1_GRP1_EnableClock (LL_AHB1_GRP1_PERIPH_GPIOB);
/* Configure SCL Pin as : Alternate function, High Speed, Open drain, Pull up */
LL_GPIO_SetPinMode (GPIOB, LL_GPIO_PIN_8, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetAFPin_8_15 (GPIOB, LL_GPIO_PIN_8, LL_GPIO_AF_4);
LL_GPIO_SetPinSpeed (GPIOB, LL_GPIO_PIN_8, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinOutputType (GPIOB, LL_GPIO_PIN_8, LL_GPIO_OUTPUT_OPENDRAIN);
LL_GPIO_SetPinPull (GPIOB, LL_GPIO_PIN_8, LL_GPIO_PULL_UP);
/* Configure SDA Pin as : Alternate function, High Speed, Open drain, Pull up */
LL_GPIO_SetPinMode (I2C1_PORT_SDA, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetAFPin_8_15 (I2C1_PORT_SDA, LL_GPIO_PIN_9, LL_GPIO_AF_4);
LL_GPIO_SetPinSpeed (I2C1_PORT_SDA, LL_GPIO_PIN_9, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinOutputType (I2C1_PORT_SDA, LL_GPIO_PIN_9, LL_GPIO_OUTPUT_OPENDRAIN);
LL_GPIO_SetPinPull (I2C1_PORT_SDA, LL_GPIO_PIN_9, LL_GPIO_PULL_UP);
// initialize I2C block
LL_I2C_Disable(I2C1);
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); // Enable clock for I2C2
LL_I2C_Disable(I2C1);
LL_I2C_SetTiming(I2C1,0x60201E2B); //from CubeMX
LL_I2C_SetOwnAddress2(I2C1, 0x00, LL_I2C_OWNADDRESS2_NOMASK); // Default
LL_I2C_Enable(I2C1);
return 0;
}
And my Read function:
uint8_t I2C_ReadChar(I2C_TypeDef *I2Cx, uint8_t Addr, uint8_t Reg, uint8_t *Value, uint8_t size)
{
LL_I2C_HandleTransfer(I2Cx, (Addr<<1), LL_I2C_ADDRSLAVE_7BIT, 1, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
while(!LL_I2C_IsActiveFlag_STOP(I2Cx)) // Loop until end of transfer received
{
/* Indicate the status of Transmit data register empty flag */
if(LL_I2C_IsActiveFlag_TXE(I2Cx))
{
/* Write data in Transmit Data register. */
LL_I2C_TransmitData8(I2Cx, Reg);
}
}
LL_I2C_HandleTransfer(I2Cx, (Addr<<1), LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
while(!LL_I2C_IsActiveFlag_STOP(I2Cx)) // Loop until end of transfer received
{
/*Check RXNE flag value in ISR register*/
if(LL_I2C_IsActiveFlag_RXNE(I2Cx))
{
/*Read character in Receive Data register.*/
*Value = LL_I2C_ReceiveData8(I2Cx);
}
}
LL_I2C_ClearFlag_STOP(I2Cx);
/* all is good, return 0 */
return 0;
}
And my first call this function is OK:
Here is my call function
if(strcmp((char *)uart_reads, ''i2c'') == 0)
{
uint8_t data[2];
I2C_ReadChar(I2C1, 0x4C, 0x00,
data
, 1); //i2C addr: 0x4C, reg 0x00, ret. val data, size 1 byteitoa(
data
[0], buffer, 10);usart_puts(buffer);
usart_puts(''\r\nI2C finish'');
}
And my first call this function is OK:

But second read from device is wrong.

Any idea, what is wrong?
#i2c-sensor-read #nucleo-f767zi