nrf-rs / nrf-hal

A Rust HAL for the nRF family of devices
Apache License 2.0
507 stars 139 forks source link

Consider supporting extended DMA transfers #11

Open hannobraun opened 6 years ago

hannobraun commented 6 years ago

This issue was first opened in the old nrf52-hal repository. Original discussion: https://github.com/jamesmunns/nrf52-hal/issues/14


The nRF52832's DMA channels are limited to buffers with a maximum length of 255 bytes. This is very limiting. For example, in the DW1000 driver, I need to support registers that are much longer than that (although there are ways to read/write subsets).

There is a way to use multiple consecutive buffers to circumvent this limitation. The product specification alludes to this (see section 10.1), but doesn't really explain how this works. I found the following discussions that provide a clearer picture:

Since this technique requires additional system resources (PPI, TIMER) and applies to all DMA channels, I think it's probably best to provide this as a separate layer that builds on top of DMA users like SPIM.

jamesmunns commented 5 years ago

Hey @hannobraun, do you think a solution like https://github.com/nrf-rs/nrf52-hal/pull/40 would work? My idea would be roughly as follows:

hannobraun commented 5 years ago

@jamesmunns I left some comments in your pull request. Whether it is an alternative to the approach suggested in this issue, I don't know. My impression is that this approach would enable the blocking API to support larger buffers with little hassle (from the user's perspective). You're suggesting a non-blocking API, which seems somewhat orthogonal.

Yatekii commented 5 years ago

I used exactly that feature of the nRF52832 in C already and it's really not that much sorcery. You need to set some triggers on the PPI bus accordingly to start the next transfer with the transfer done event. You will still require some stop condition (e.g. an ISR) that stops the chain of write/read events, such that it does not trigger the chain for all eternity (I think this is kinda sad and I would have loved a register to set a max transfers value or total buffer size).

I think this should be easily doable but would require some nicer higher level interface to the PPI bus.

hannobraun commented 5 years ago

I think this should be easily doable but would require some nicer higher level interface to the PPI bus.

Which would be a nice thing to have in itself!