cancel
Showing results for 
Search instead for 
Did you mean: 

Why HAL DMA functions are not working?

TurboSlow
Associate II

Hello Guys,

I am trying to read data via I2C bus using HAL_I2C_Master_Receive_DMA and HAL_I2C_Mem_Read_DMA, but both are not working

If I use HAL_I2C_Master_Receive it is working

I tried to manually disable and then re-enable DMA channel used by setting enable bit but this doesn't help

If I add DMA function in addition to HAL_I2C_Master_Receive iw also stoped working except on first use.

Also in debugger instruction marker is skipping DMA functions

I tried to add volatile to array definition and to set compilator optimization level to 0, but nothing helped

I tried my simple code in uVision5 and True Studio debuggers and result is the same, DMA functions are not working

Could you help me with this issue and give me some examples of using above functions?

11 REPLIES 11

Which STM32 architecture are you using?

The F7 and H7 both have special considerations about memory involved and caching.

Is the DMA unit flagging an error?​ At what address is your buffer.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
TurboSlow
Associate II

I am using stm32f103

What error could give DMA if it is compiled without errors? And what is difference at what address is my buffer? It is there where compiler put it

Also I could add that my test project is configured using CubeMX

The compiler just identifies syntax errors, not issues with logic or function, or those which present dynamically.

The DMA units themselves have status registers that should report error/fault conditions related to the transfer. Review these in the debugger's peripheral view, or dump out the content with telemetry messages.

I2C devices might cause things to abort if the ACK signals don't occur as expected. Consider using a scope or logic analyzer to review for signalling issues, or clues on what is occurring there.

The auto-generators should create workable code, but I'm not sure I have much faith in them. The HAL code trees also contain examples. Check that all the appropriate IRQHandlers are in place.

Sorry not using CubeMX or F1 series parts.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal

If using HAL, my understanding is that once a dma is used witg a peripheral, only peripheral hal functions should be used, not dma's. This includes callbacks.

TurboSlow
Associate II

So could you give me example for usage of above functions?

I need to see working code and not want to debug HAL

MNapi
Senior II

This is the problem with STM they do not give you any sample codes to learn. Arduino has a lot of examples this is why it became so popular.

Try to find you have have the right address first.

for(uint16_t i=0; i<255; i++){

   if(HAL_I2C_IsDeviceReady(&hi2c1, i, 2, 10) == HAL_OK)

   {

      HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);

      break;

   }

i is of course the address you seek, 2 means you try to times, 10 is 10 ms timeout

you need to enable DMA for I2C i cubeMX first

and it should work

HAL_I2C_Master_Transmit_DMA(&hi2c1, 0xD8, i2cData, 2);

2 is the side of data,

0xD8 you sample address

  1. 0690X000006D9ovQAC.jpgI know that address is correct because HAL_I2C_Master_Receive is working
  2. DMA in CubeMX is enabled and configured
  3. When I debug HAL_I2C_Master_Receive_DMA going step by step

if(hi2c->State == HAL_I2C_STATE_READY) never pass

Maybe there is something special in DMA configuration that I need to do?

SDall
Associate II

hi I'm also trying to use i2c with dma but it doesn't work. first I send data to arduino without dma hal_i2c_master_transmitt, and it works perfectly then I do the same thing with the hal_i2C_master_trasmit_dma but it doesn't work, can anyone tell me the reason?

TTran.1
Associate

I had beeb struggling with the same problem on STM32F407 and I2C1.

After searching for potential bugs in the program flow, i found out that the function HAL_I2C_Master_Transmit_DMA leads to following line:

dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);

After the first transfer, this won't return HAL_OK, which is necessary for the transmission to continue.

So my solution was simply abort the previous DMA interrupt in the callback function which is called after the transmission has completed. The same can be implied with HAL_I2C_Master_Receive_DMA. To resolve the problem, i added the following callback functions in main.c:

void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)

{if (hi2c->Instance==hi2c1.Instance)

   {HAL_DMA_Abort_IT(hi2c->hdmatx);

   }

}

void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)

{if (hi2c->Instance==hi2c1.Instance)

   { HAL_DMA_Abort_IT(hi2c->hdmarx);

   }

}

Hope this will help you, please consider this is only a workaround. If someone finds out, i would like to know more about the reason of this bug.