2017-01-18 07:20 AM
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
#l42017-01-18 03:01 PM
What's the content of hi2c1 and the I2C registers?
JW
2017-01-19 01:32 AM
Hi,
I made a snapshot of the variable, when the system runnes inside the HAL_I2C_GetState.
regards Roger
2017-01-19 03:23 PM
And the interrupt handlers are set how?
JW
2017-01-19 04:05 PM
Hi,
I hope this is the right source code you are looking for!?
regards Roger
stm32l4xx_it.c
void DMA1_Channel6_IRQHandler(void)
{ /* USER CODE BEGIN DMA1_Channel6_IRQn 0 *//* USER CODE END DMA1_Channel6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_i2c1_tx); /* USER CODE BEGIN DMA1_Channel6_IRQn 1 *//* USER CODE END DMA1_Channel6_IRQn 1 */
}/**
* @brief This function handles DMA1 channel7 global interrupt.*/void DMA1_Channel7_IRQHandler(void){ /* USER CODE BEGIN DMA1_Channel7_IRQn 0 *//* USER CODE END DMA1_Channel7_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_i2c1_rx); /* USER CODE BEGIN DMA1_Channel7_IRQn 1 *//* USER CODE END DMA1_Channel7_IRQn 1 */
}dma.c
/* DMA1_Channel6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
/* DMA1_Channel7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
2017-01-19 05:36 PM
Hello,
When you use DMA with I2C to Transmit or Receive data, you should
Enable I2Cx_ER_IRQn and I2Cx_EV_IRQn interrupts.
because they all called I2C_DMAXferCplt (hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt)
and it enable interrupt call to handle I2C state.
__HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
2017-01-20 12:36 AM
Hi,
when I insert into i2c.c the lines
HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C1_ER_IRQn); HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0); HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);the system runnes into this Assember line
WWDG_IRQHandler:
080137b0: b.n 0x80137b0 <WWDG_IRQHandler>2017-01-21 07:02 AM
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{GPIO_InitTypeDef GPIO_InitStruct;
if(i2cHandle->Instance==I2C1) { /* USER CODE BEGIN I2C1_MspInit 0 *//* USER CODE END I2C1_MspInit 0 */
....
__HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c1_rx);......__HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c1_tx);
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0); HAL_NVIC_EnableIRQ(I2C1_EV_IRQn); HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0); HAL_NVIC_EnableIRQ(I2C1_ER_IRQn); /* USER CODE BEGIN I2C1_MspInit 1 *//* USER CODE END I2C1_MspInit 1 */
}}2017-01-23 12:57 AM
Hi,
this is the I2C_MSPInit that I'm actually running.
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{GPIO_InitTypeDef GPIO_InitStruct;
if(i2cHandle->Instance==I2C1) { /* USER CODE BEGIN I2C1_MspInit 0 *//* USER CODE END I2C1_MspInit 0 */
/**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);
/* USER CODE BEGIN I2C1_MspInit 1 */
// NVIC for I2Cx
HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0); HAL_NVIC_EnableIRQ(I2C1_ER_IRQn); HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0); HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);/* USER CODE END I2C1_MspInit 1 */
}}
2017-10-17 12:39 AM
Hello
Heil.R
,I'm having the same issue.
Did you find the solution ?