cancel
Showing results for 
Search instead for 
Did you mean: 

Should I set HAL_DMA_STATE_READY in circular mode?

Stijn1
Associate II

Hi,

I'm implementing a circular buffer for UART transmit via DMA on an STM32L4 device.

I've got a callback that updates the read pointer and calls another HAL_UART_Transmit_DMA if it's still not equal to the write pointer.

This callback is called by:

HAL_DMA_IRQHandler (stm32l4xx_hal_dma.c)

hdma->XferCpltCallback

which currently points to UART_DMATransmitCplt from stm32l4xx_hal_uart.c.

which calls HAL_UART_TxCpltCallback

which contains my callback

When I look at the function HAL_DMA_IRQHandler, it conditionally sets hdma->State = HAL_DMA_STATE_READY; only when NOT in circular mode. BUT I've initialized DMA in circular mode.

Does this mean that it's expected of me to set hdma->State = HAL_DMA_STATE_READY; after my callback found no more data in the circular buffer and I'm not calling another transmit?

I want to use this state to decide whether I have to manually start a new transmission after adding data to the circular buffer.

4 REPLIES 4
n2wx
Senior

I don't have a good answer but you answered a question that I had. Before I totally abandoned HAL I wrote ADC DMA stuff and it's in circular mode. I found that I had to do a Stop_DMA to overcome the wrong-state issue you just identified.

Are you doing circular DMA on a circular ring buffer?

Stijn1
Associate II

I discovered more problems after just setting the DMA state and then abandoned that strategy.

I am using an array and two pointers as circular buffer. My transmit function fills the buffer and handles the wrap around. This means that when sending more than the end of the buffer, I just use a Transmit_DMA up to the final byte of the buffer and let my TX complete callback handle the discovery that there's more to write at the beginning of the buffer. (The wrap around part)

This means that I can just use DMA_MODE_NORMAL and figure it out that way.

Long story short: solved.

I'm still curious about the intended use of MODE_CIRCULAR though. Couldn't find a good code example from ST.

berendi
Principal

Changing undocumented fields of a handle is generally not recommended. Even if you can look at the sources in this case, there is no guarantee that the implementation of that field won't change in the next release, or just disappear.

The HAL library does not cover the full functionality of the hardware, and it's quite poorly documented, it's very hard if not impossible to tell what is the proper way to achieve a certain functionality, or whether there is one at all.

Stijn1
Associate II

I really like the HAL library for one specific use: one source code runs on both STM32L0 and STM32L4 devices and the source can be made completely portable between these with minimal product specific files and defines.

Using the LL drivers wouldn't have made this possible.

And updating the drivers is not desired anyway. Why would we, once everything runs? That's just creating work.

But I do see the limitations too. It's getting more and more complete but some oddball things are just simply not possible using HAL.

This is getting off-topic.

I solved my issue by choosing an other way.