cancel
Showing results for 
Search instead for 
Did you mean: 

I2C integration using DMA Driver

Piyoosh
Associate III

Hi All,

I am integrating the IMU sensor Using I2C DMA in circular mode on stm32f103c8t6 using Hal Library, so facing an issue reading the address value.

In the below code "HAL_I2C_STATE_READY " this flag is not resetting after once function executes so in 2nd execution this HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) function is not trigering to DMA Handler function. 

if (hi2c->State == HAL_I2C_STATE_READY) { /* Wait until BUSY flag is reset */ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U); do { count--; if (count == 0U) { hi2c->PreviousState = I2C_STATE_NONE; hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; return HAL_BUSY; } } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); /* Process Locked */ __HAL_LOCK(hi2c); /* Check if the I2C is already enabled */ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) { /* Enable I2C peripheral */ __HAL_I2C_ENABLE(hi2c); } /* Disable Pos */ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS); hi2c->State = HAL_I2C_STATE_BUSY_RX; hi2c->Mode = HAL_I2C_MODE_MEM; hi2c->ErrorCode = HAL_I2C_ERROR_NONE; /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; hi2c->XferSize = hi2c->XferCount; hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->Devaddress = DevAddress; hi2c->Memaddress = MemAddress; hi2c->MemaddSize = MemAddSize; hi2c->EventCount = 0U; /* Enable Acknowledge */ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK); /* Generate Start */ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START); /* Process Unlocked */ __HAL_UNLOCK(hi2c); if (hi2c->XferSize > 0U) { /* Note : The I2C interrupts must be enabled after unlocking current process to avoid the risk of I2C interrupt handle execution before current process unlock */ /* Enable EVT, BUF and ERR interrupt */ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); } return HAL_OK; }
View more

 

2 REPLIES 2
TDK
Super User

How are you calling the HAL functions and what you're expecting to happen?

If you feel a post has answered your question, please click "Accept as Solution".
Saket_Om
ST Employee

Hello @Piyoosh 

The HAL_I2C_STATE_READY flag is not reset immediately after the execution of HAL_I2C_Mem_Read_DMA(). Instead, the state remains busy until the transfer is complete. The end of the transfer is indicated by the invocation of the HAL_I2C_MemRxCpltCallback() function. To ensure that a subsequent transfer can be initiated successfully, you can either call the next transfer within the callback function or set a flag within this function and check it in the main loop before initiating the second transfer.

Please refer to the implementation in the code snippet below:

volatile uint8_t transferCompleteFlag = 0; void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) { // Set the flag to indicate the transfer is complete transferCompleteFlag = 1; } void I2C_Read_DMA(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) { // Start the I2C memory read using DMA if (HAL_I2C_Mem_Read_DMA(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, Size) != HAL_OK) { // Handle error } } int main(void) { // HAL initialization HAL_Init(); // System clock configuration SystemClock_Config(); // I2C initialization MX_I2C1_Init(); uint8_t data[10]; uint16_t deviceAddress = 0x50; uint16_t memoryAddress = 0x00; // First I2C read transfer I2C_Read_DMA(deviceAddress, memoryAddress, data, sizeof(data)); // Wait for the first transfer to complete while (transferCompleteFlag == 0) { // Optionally, you can add a timeout mechanism here } // Reset the flag for the next transfer transferCompleteFlag = 0; // Second I2C read transfer I2C_Read_DMA(deviceAddress, memoryAddress + 10, data, sizeof(data)); // Main loop while (1) { // Application code } }
View more

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om