cancel
Showing results for 
Search instead for 
Did you mean: 

difference between HAL_I2C_Mem_Write() and HAL_I2C_Mem_Write_DMA()

dspark
Associate II
Posted on July 03, 2016 at 10:49

Hello,

I generated the code using the STM32CubeMx.

I'm trying to I2C communication between STM32F4(master) and IC(slave, 7bit address).

I tested to two functions for I2C communication.

HAL_I2C_Mem_Write is OK, but HAL_I2C_Mem_Write_DMA is fail.

Test condition and setting parameters are same only except the function.

please let me know why HAL_I2C_Mem_Write_DMA() is didn't work.

thank you.

==================================================================

//test code

/* I2C1 init function */

static void MX_I2C1_Init(void)

{

  hi2c1.Instance = I2C1;

  hi2c1.Init.ClockSpeed = 100000;

  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;

  hi2c1.Init.OwnAddress1 = 0;

  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

  hi2c1.Init.OwnAddress2 = 0;

  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

  if (HAL_I2C_Init(&hi2c1) != HAL_OK)

  {

    Error_Handler();

  }

}

static void MX_DMA_Init(void) 

{

  /* DMA controller clock enable */

  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */

  /* DMA1_Stream0_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);

  /* DMA1_Stream2_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);

  /* DMA1_Stream4_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);

  /* DMA1_Stream6_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);

}

void main(void)

{

         uint8_t error;

         uint8_t data[3];

         data[0] = 0x47;

         error = HAL_I2C_Mem_Write(&hi2c1, 0x82, 0x3f, 1,  data, 1,100); //succeed

         error = LT_I2C_Write_DMA(&lt_i2c1_, 0x82, 0x3f, data, 1); //fail

}

success: HAL_I2C_Mem_Write(Dev Add: 0x82, Mem Add: 0x3f, data: 0x47)

0690X000006039ZQAQ.jpg

FAIL: HAL_I2C_Mem_Write_DMA(Dev Add: 0x82, Mem Add: 0x3f, data: 0x47)

0690X000006039eQAA.jpg
12 REPLIES 12
slimen
Senior
Posted on July 03, 2016 at 23:29

Hi,

You can find the needed for your project under this application which can help you as an implementation example to develop your application:

STM32Cube_FW_F4_V1.12.0\Projects\STM32F4-Discovery\Examples\I2C\I2C_TwoBoards_ComDMA

This example guides you through the different configuration steps to ensure I2C Data buffer transmission and reception with DMA.

Regards
blacksu6
Associate II
Posted on March 11, 2017 at 14:43

Hi

,

I also have the same problem you encountered . Do you have the answer about this defeat issue?  If you solved this problem, can you give me some hints?

P.S.   I2C(API functions) test result as below

   1.

HAL_I2C_Mem_Write

  -->OK

   2.

HAL_I2C_Mem_Read

  -->OK

   3.

HAL_I2C_Mem_Write_DMA

  -->NG

   4 

HAL_I2C_Mem_Read_DMA

  -->OK

  

Regards             

6740493
Associate
Posted on May 03, 2017 at 15:42

Hello.

When you use

HAL_I2C_Mem_Write_DMA

 it's freeze because master doesn't send Stop

condition. You must enable I2C event interrupt. In this interrupt call I2C_MasterTransmit_BTF for generate Stop condition.

Regards   

Posted on August 02, 2017 at 21:48

Cool! It's works! Thank you.

Posted on August 03, 2017 at 10:14

Sergei Litovko wrote:

Cool! It's works! Thank you.

https://community.st.com/0D50X00009bMM5DSAW

 
Posted on February 12, 2018 at 01:22

Thank you.

Posted on March 13, 2018 at 10:51

Hi,

Could you please explain what do you mean by enabling I2C event interrupt and call I2C_MasterTransmit_BTF ?

Because I am using the I2C_Mem_Write_DMA and somehow, the code is in interrupt endless loop. 

void I2C1_IRQHandler(void)

{

      if(hi2c1->Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR))

      {

            HAL_I2C_ER_IRQHandler(hi2c1);

      }

      else

      {

            HAL_I2C_EV_IRQHandler(hi2c1);

      }

}

static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources)

{

      uint16_t devaddress = 0U;

      uint32_t xfermode = 0U;

      /* Process Locked */

      __HAL_LOCK(hi2c);

      ************************

      ************************

      else if(((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET))

      {

            /* Call I2C Master complete process */

            I2C_ITMasterCplt(hi2c, ITFlags);

      }

      /* Process Unlocked */

      __HAL_UNLOCK(hi2c);

   return HAL_OK;

}

In 

I2C_Master_ISR_DMA function, the 

 

__HAL_LOCK return a busy flag and cannot proceed with upper layer function in my application. Basically, the program is contenstly in interrupt with dead lock. 

How this could happen on I2C line ?

Is the issue on HAL itself because it is reponsible to take care of all interrupt and lock boolean ?

Thanks in advance for your supports.

Best regards,

189565CGIL3
Frank CA
Associate III
Posted on April 04, 2018 at 18:00

I recently posted about exactly this issue, unfortunately I had not seen this post, would have saved me some time! My post

https://community.st.com/0D50X00009XkVw0SAF

...