Skip to main content
Youssouf Coulibaly
Associate II
July 6, 2017
Solved

STM32F091RC I2C DMA transfer complete

  • July 6, 2017
  • 1 reply
  • 1965 views
Posted on July 06, 2017 at 08:00

Hello everybody,

I am using I2C interface in master mode to collect data from external slave device with DMA in non-blocking mode.

- HAL_I2C_Master_Transmit_DMA

- HAL_I2C_Master_Receive_DMA

My program is working fine since I get correct data.

BUT I would like to get an event that the exchanges are completed by registering these functions during INIT step :

-  // HAL Register DMA Tx Transfer events

 HAL_DMA_RegisterCallback(dmaHandleTx, HAL_DMA_XFER_CPLT_CB_ID, i2cTransmitFullCallback)

- // HAL Register DMA Rx Transfer events

 HAL_DMA_RegisterCallback(dmaHandleRx, HAL_DMA_XFER_CPLT_CB_ID, i2cReceiveFullCallback)

When I run my program, I get DMA interrupt in below function but no callback call is triggered. 

void DMA1_Ch2_3_DMA2_Ch1_2_IRQHandler(void)

{

   HAL_DMA_IRQHandler(

dmaHandleTx

);

   HAL_DMA_IRQHandler(

dmaHandleRx

);

}

I tried to look carefully inside the HAL itself and I found something quite strange from my understanding.

HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)

{

      /* Set the I2C DMA transfer complete callback */

      hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;

      /* Set the DMA error callback */

      hi2c->hdmatx->XferErrorCallback = I2C_DMAError;

      /* Set the unused DMA callbacks to NULL */

      hi2c->hdmatx->XferHalfCpltCallback = NULL;

      hi2c->hdmatx->XferAbortCallback = NULL;

      /* Enable the DMA channel */

      HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);

}

If the Callback function pointer is initialize at each call of HAL_I2C_Master_Transmit_DMA function with internal I2C_DMAMasterTransmitCplt, how it manages my registered callback in INIT step (i2cTransmitFullCallback) ?

Does anyone has an idea about this ?

Thanks a lot.

    This topic has been closed for replies.
    Best answer by Zt Liu
    Posted on July 07, 2017 at 11:47

    hi, if you just want callbacks after HAL_I2C_Master_Transmit_DMA and HAL_I2C_Master_Receive_DMA routines,

    You just need to implement your 

    void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);

    void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);

    they are weakly defined in stm32f0xx_hal_i2c.c,

    Don't forget to enable I2Cx event global interrupt. So that in your stm32f0xx_it.c, 

    you will see something like

    void I2Cx_IRQHandler(void)

    {

       HAL_I2C_EV_IRQHandler(&I2cHandle);

       HAL_I2C_ER_IRQHandler(&I2cHandle);

    }

    Good Luck!

    1 reply

    Zt Liu
    Zt LiuBest answer
    Senior III
    July 7, 2017
    Posted on July 07, 2017 at 11:47

    hi, if you just want callbacks after HAL_I2C_Master_Transmit_DMA and HAL_I2C_Master_Receive_DMA routines,

    You just need to implement your 

    void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);

    void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);

    they are weakly defined in stm32f0xx_hal_i2c.c,

    Don't forget to enable I2Cx event global interrupt. So that in your stm32f0xx_it.c, 

    you will see something like

    void I2Cx_IRQHandler(void)

    {

       HAL_I2C_EV_IRQHandler(&I2cHandle);

       HAL_I2C_ER_IRQHandler(&I2cHandle);

    }

    Good Luck!

    Youssouf Coulibaly
    Associate II
    July 7, 2017
    Posted on July 07, 2017 at 16:06

    Hi Zhitai Liu,

    Thanks for your support Now I get interrupt callback to my upper layer.

    Using:

    0690X00000607SzQAI.png0690X00000607T9QAI.png