Closed sajattack closed 3 years ago
Resources: http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42257-SAM-Direct-Memory-Access-Controller-Driver-DMAC_ApplicationNote_AT07683.pdf http://asf.atmel.com/docs/latest/samd21/html/dma_8c.html https://gist.github.com/sajattack/5080311aa5085f1a9748c711bea78140 https://github.com/adafruit/adafruit_zerodma https://github.com/rust-embedded/embedded-hal/issues/37
How closely should we follow the ASF4 API @wez? What have you been doing so far?
I haven't really looked at DMA on this device in detail. I recall reading the blog posts referenced from the embedded-hal issue you referenced, and have been soft-following that issue.
My currently under-educated opinion is that we should feel free to produce an implementation that works for us (eg: we don't have to wait for a trait to appear in embedded-hal), and that implementation should be reasonably rust idiomatic and safe rather than mirroring an unsafe C API that exists elsewhere.
That said, I haven't really looked at the DMA APIs for C/C++ on this device so I don't know whether I'm being too much of a rust snob, and it can be better to start out by building something (or anything!) that does the job so that there is a concrete implementation as a starting point that we can then comment on as a PR and give suggestions in review, rather than blocking on consensus in this issue.
After skimming a couple of things, I have a couple of questions on my mind that would influence how I might choose to design the API, so I'm going to ask them here; I'd like to stress that I still don't know enough to have a strong influence on direction.
Our clock allocation is pretty robust and type safe and is one model that we could potentially apply to this, but I don't know if is convenient enough to translate to DMA.
It looks to me like channels can be released and reallocated on the fly.
One idea I had was making a new()
with all the initialization rather than like 5 or however many initialization functions the C version has.
Follow my progress here https://github.com/sajattack/atsamd/tree/dma
This gist has some earlier work I did on SERCOM DMA: https://gist.github.com/tarcieri/61d5789e369cf5e25edc4248d26b525a
It seems like future attempts at adding DMA should be leveraging https://github.com/rust-embedded/embedded-dma
Just to document, and building on what @tarcieri said, there seems to have been some progress made regarding DMA. Relevant links:
https://github.com/rust-embedded/wg/issues/480 https://github.com/rust-embedded/embedded-dma https://github.com/ra-kete/dma-poc
just saw this https://crates.io/crates/samd-dma
I have written a DMA driver that seems to be working quite well. For now it only works for the SAMD21 chips, but it could easily be adapter to all the chip families supported by this HAL. This is a pure Rust driver and is not derived from any existing C/C++ library. Currently it only builds on rustc 1.51, since it uses const generics pretty heavily. It aims to support 4 kinds of DMA transfers:
Transfers are supported for i8, u8, i16, u16, i32, u32
and f32
beat sizes.
The idea was to have a safe driver that statically guarantees the DMAC and the individual channels are correctly configured before launching transfers. It is not meant to be just a wrapper to the DMAC registers.
Channels are accessible individually through a split() method on the DMAC. They can be reused after a transfer is complete.
The driver does not handle interrupts or callbacks, although it is possible to enable interrupts on a channel-to-channel basis through the driver. The user would then be responsible for clearing the interrupt flags in the ISR.
Take a look here: https://github.com/jbeaurivage/atsamd-rs/tree/dmac. An example is available for the Feather M0.
For now, I plan on refining the driver and submit a PR in time for rustc 1.51 stabilization. I would love comments, advice or suggestions!
@jbeaurivage would be great to have SAMD51 support as well. Perhaps https://crates.io/crates/samd-dma or #60 could serve as an inspiration?
Title kinda speaks for itself. I'll try to work on this but will probably need help.