AnsweredAssumed Answered

I2C endless loop in HAL_I2C_GetState

Question asked by Roger Heil on Jan 18, 2017
Latest reply on Oct 17, 2017 by Alexandre T

Hi,

 

im using a STM32L476RG and want to interace an extrenal RTC via I2C.

 

cube = 4.19.0

lib L4 = 1.6.0

 

hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x10909CEC;
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;

 

/**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_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();

/* Peripheral DMA init*/

hdma_i2c1_rx.Instance = DMA1_Channel7;
hdma_i2c1_rx.Init.Request = DMA_REQUEST_3;
hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c1_rx);

hdma_i2c1_tx.Instance = DMA1_Channel6;
hdma_i2c1_tx.Init.Request = DMA_REQUEST_3;
hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(i2cHandle,hdmatx,hdma_i2c1_tx);

 

 

Sourcecode:

 

while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){ }
if(HAL_I2C_Master_Transmit_DMA(&hi2c1, RTC_ADDRESS, (uint8_t*)txBuffer, TX_BUFFERSIZE)!= HAL_OK)
{
Error_Handler();
}
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){ }

 

So I'm waiting until the bus is free. But after the first transmit, the HAL_I2C_GetState never get ready!

 

 

 

The logic analyser detects a ACK for the  RTC.

 

Could someone help me? I read a lot of forum sides, but do not found a concret solution for this problem.

 

regards

Roger

Outcomes