Skip to main content
TurboSlow
Associate
January 18, 2019
Question

Why HAL DMA functions are not working?

  • January 18, 2019
  • 10 replies
  • 3528 views

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?

10 replies

Tesla DeLorean
Guru
January 18, 2019

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 VenmoUp vote any posts that you find helpful, it shows what's working..
TurboSlow
TurboSlowAuthor
Associate
January 18, 2019

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

Tesla DeLorean
Guru
January 18, 2019

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 VenmoUp vote any posts that you find helpful, it shows what's working..
S.Ma
Principal
January 18, 2019

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
TurboSlowAuthor
Associate
January 18, 2019

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
January 18, 2019

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

TurboSlow
TurboSlowAuthor
Associate
January 18, 2019
  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 III
March 26, 2020

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
Visitor II
June 27, 2020

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.

RMirz.1
Visitor II
June 30, 2020

Доброго времени �?уток, �?толкнул�?�? �? похожей проблемой при работе �? DMA на контроллере f103. В проекте и�?пользовали�?ь два DMA один дл�? каналов �?ЦП (DMA ADC), второй дл�? отправки преобразованных значений �?ЦП на второй микроконтроллер f103, дл�? отображени�? их на tft �?кране (USART DMA). DMA �?ЦП �? и�?пользовал в режиме circular, а DMA USART вызывал в теле бе�?конечного цикла. В итоге таким образом ничего не работало, USART DMA не отправл�?л значени�?, работал только обычный USART Tx, но его �?коро�?ти мне не до�?таточно. Вы�?�?нил что USART DMA не �?бра�?ывает флаг готовно�?ти HAL_UART_STATE_BUSY, он в�?егда зан�?т �? так пон�?л из за circular в �?ЦП. Убрал circular в �?ЦП и начал его опрашивать в бе�?конечном цикле, �?то помогло но �?коро�?ть в�?ей �?и�?темы почему-то упала, так как на втором f103 который управл�?л tft, на �?кране было видно �?ловно чи�?ла формируют�?�?, �?то т�?жело объ�?�?нить но в общем медленнее. В итоге вернул circular, и начал про�?то �?бра�?ывать �?тот флаг в ручную по�?ле отправки значений �? USART DMA.

Вот так:

HAL_UART_Transmit_DMA(&huart2,(uint8_t *) str, sizeof(str)-1);

huart2.gState = HAL_UART_STATE_READY;

В�?е заработало, �?коро�?ть �?и�?темы выро�?ла в разы.

Возможно �?то неправильно, вот надею�?ь вы мне поможете, решить проблему без "ко�?тылей".

Mariano Iadaresta
Associate II
March 19, 2025

Hi,

 

I use HAL_I2C_Mem_Read_DMA to read IMU and magnetometer data from LSM9ds1

 

in loop():

//read acceleometer

if (accReady) {

// Reset flags for continuous operation

accReady = 0;

while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)

{

}

// Restart readings

HAL_I2C_Mem_Read_DMA(&hi2c1, LSM9DS1_IMU_I2C_ADD_H , LSM9DS1_OUT_X_L_XL, I2C_MEMADD_SIZE_8BIT, rxDataACC, RX_BUFF_LEN);

}

 

the callback:

 

void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) {

if (hi2c->Instance == I2C1) {

if (!accReady) {

// acc read complete, start accelerometer read

accReady = 1;

}

HAL_DMA_Abort_IT(hi2c->hdmarx);

}

}