nuttx icon indicating copy to clipboard operation
nuttx copied to clipboard

[FEATURE] STM32H5 DMA Driver

Open stbenn opened this issue 8 months ago • 7 comments

Is your feature request related to a problem? Please describe.

I am working on adding support for DMA on the STM32H5 architecture. The H5 uses the GPDMA peripheral, which is unlike any of the STM DMA peripherals with drivers implemented in NuttX (The GPDMA peripheral is shared between STM32H5, STM32H7Rx/7Sx, STM32U5, STM32U3).

The GPDMA peripheral is powerful but quite a bit more complex than other STM DMA implementations. For anything beyond a simple one-shot transfer, it requires programming a linked-list data structure into memory.

I am opening this ticket to get feedback on what solution might fit best in NuttX.

Describe the solution you'd like

There are two directions I have considered:

First: Give full control over channel registers for configuration.

  • Pros: Flexibility and simpler DMA driver implementation.
  • Cons: Added complexity when using DMA driver. e.g. ADC driver would need to allocate a linked list item in memory to do a circular DMA transfer.

Second: Abstract away registers by using a 'behavior' configuration (e.g. Just select 'circular mode' instead of having to go through creating the entire linked list item configuration).

  • Pros: Interface similar to current DMA implementations. Simpler usage from other drivers. e.g. ADC driver tells DMA 'use circular' and the DMA driver handles linked list item allocation and configuration.
  • Cons: Less flexible and more complex DMA driver implementation. DMA driver may require future work if a peripheral needs more advanced features such as 2D addressing or in-transit data manipulation.

Describe alternatives you've considered

No response

Verification

  • [x] I have verified before submitting the report.

stbenn avatar Apr 22 '25 14:04 stbenn

@stbenn send it to the mailing list as well, since some developers are not paying attention on NuttX issues

acassis avatar Apr 22 '25 15:04 acassis

@acassis Thank you for the suggestion, I will create one and send it out.

stbenn avatar Apr 22 '25 16:04 stbenn

A hybrid between these two options may also be an option. Have a set of base functions that use a full register configuration structure. Then, provide helper functions to generate config for common use cases, such as circular.

stbenn avatar Apr 22 '25 19:04 stbenn

Thank you @stbenn for this idea and work! You are probably the best person to decide as you know the details best :-) I think @raiden00pl is also using STM chips and can provide good feedback :-)

If you think that STM32H5 is specific enough to have its own implementation then it should be noted in the documentation and go that path to get most out of the hardware.

Note however that in the best situation existing code from other STM architectures should be portable to H5 from the upper half driver perspective (i.e. application). How things are implemented in the lower half driver is hardware specific.

Do I understand correctly that STMH5 somehow implies DMA implementation other from existing implementations in NuttX in general or just other STM chips?

Would it be possible to use peripherals "the old way" if no DMA is used?

cederom avatar Apr 22 '25 23:04 cederom

Please make the GDMA implementation as similar to the rest of DMA implementations in STM32 as possible: similar API and all work that belongs to DMA driver is done in DMA driver.

Remember that if GDMA is used in the STM32H7R family, then one day your implementation may be ported to STM32H7 as well and then compatibility is of great importance. Also porting other peripherals to STM32H5 that use the old DMA API will be much easier when the interface is similar. All DMA implementations in the STM32 families use a very similar API and it should remain so even if it complicates the implementation of the DMA driver itself. If you look at STM32H7 and the rest of the STM32's, even though they use different DMA implementations, the general outline of the API and its usage is very similar to the rest. In the old days when STM32H7 was still new chip, it was more visible than now: MDMA, BDMA, DMAMUX, wtf, but I put some effort to make the API and its use as close as possible to previous implementations.

So I'm definitely for the second option :)

raiden00pl avatar Apr 23 '25 07:04 raiden00pl

I was also leaning towards the second option, so I am glad to have confirmation on that.

For either option, I was planning on keeping the API the same (for all the same compatibility reasons you explained) except for stm32_dmasetup() which will require a different configuration structure. However, this already seems to be the case between STM32 DMA implementations so I don't think that will be an issue.

Focusing on Setup Configuration

Current drivers give access to channel control registers, which works because those peripherals have most behavior defined in 1 or 2 (for H7 MDMA) registers. The H5 spreads it across 3 registers (or 7 for 2D channels), with one big caveat... common functionality like continuous DMA, circular buffer, and double buffer are not register configurations. This is why there needs to be at least some level of abstraction.

There are three ways I can think of to do this, and I am open to other suggestions as well:

  1. Define a structure to specify behavior instead of registers. Have struct members for data size, address incrementing, burst length, etc.
  2. Use pseudo-control registers. These would be well defined in the H5 DMA header file. Essentially the same abstraction as above, but packed into uint32_t with fields used to specify behavior.
  3. Give access to CxCR, CxTR1, CxTR2 registers and add an additional options member to turn on special modes (continuous/circular, double buffer, etc.). If a special mode is given, the DMA driver uses the provided control registers when allocating linked list items necessary for that mode.

There's TONS of functionality this peripheral provides that could be used bare-metal, but don't necessarily fit in the NuttX DMA model (or at least my understanding of said model). So, I am trying to find a good balance of giving access to these functionality while still fitting into how DMA is used in Nuttx.

stbenn avatar Apr 23 '25 14:04 stbenn

@raiden00pl and @acassis, I have made some decent progress and will hopefully be creating a PR for this in the next week. In the meantime, I have a question regarding the PR.

The best way I could find to test the DMA driver is to also implement DMA support for the H5 ADC driver. I have kept the ADC and DMA development in separate branches, with the ADC branch rebasing/merging in changes made to the DMA branch (i.e. the ADC branch is the DMA branch + ADC specific development).

Should these be separate PRs or one with multiple commits (one for DMA and one for ADC)? It is my understanding that typically they would be separate PRs, but in this case the ADC update is needed to test the DMA driver.

If you have any suggestions for testing the DMA driver that you think would be better, please let me know!

stbenn avatar May 02 '25 13:05 stbenn