Git Product home page Git Product logo

Comments (5)

jannic avatar jannic commented on August 11, 2024 1

I don't think this is currently supported.

It also looks like the documentation is not correct. https://docs.rs/rp2040-hal/latest/rp2040_hal/dma/index.html contains the sentence: "This API tries to provide three types of buffers: Single buffers, double-buffered transfers where the user can specify the next buffer while the previous is being transferred, and automatic continuous ring buffers consisting of two aligned buffers being read or written alternatingly." I think this is wrong and the "continuous ring buffer" mode currently is not implemented. Or at least it's not obvious how to use the API in that mode.

Due to the way the hardware is implemented, even if you only want to send the contents of a single buffer continuously, you need two DMA channels. It is not possible to chain a channel to itself. And if the continuous mode needs two DMA channels anyway, it might be reasonable to extend double_buffer to support this use case. However from a usability and discoverability point of view, it might be better to have a separate mode.

from rp-hal.

jsgf avatar jsgf commented on August 11, 2024

As a side note, I was surprised that the API doesn't let you set up a chain before starting the transfer. The current API is awkward if you know there's a chain but you're essentially racing with the transfer in flight.

from rp-hal.

jsgf avatar jsgf commented on August 11, 2024

Also it doesn't have a way to group channels so you can start them simultaneously.

from rp-hal.

jannic avatar jannic commented on August 11, 2024

As a side note, I was surprised that the API doesn't let you set up a chain before starting the transfer. The current API is awkward if you know there's a chain but you're essentially racing with the transfer in flight.

The current API makes sense for the designated use case: In a common double-buffer setup, you want to have full access to the second buffer from your Rust code while the first buffer is used by DMA. To avoid data races (and therefore undefined behavior), the API can't setup the chaining to the second buffer before the caller cedes its reference to that buffer.

Of course, this focus on a particular use case is also limiting. If your buffers are small and the DMA speed is fast, buffer underruns become possible, and the API provides no way to compensate.

But it is difficult to design an API that is both safe and flexible. And for full flexibility, it's still possible to configure the DMA registers using the PAC.

(That doesn't mean that there's no room for improvement! And tickets like this one are useful and important to learn about actual use cases that could be better supported. I'm just explaining the status quo.)

Also it doesn't have a way to group channels so you can start them simultaneously.

Can you provide an example where this would be important?

from rp-hal.

jsgf avatar jsgf commented on August 11, 2024

Of course, this focus on a particular use case is also limiting. If your buffers are small and the DMA speed is fast, buffer underruns become possible, and the API provides no way to compensate.

Right. I'm thinking about things like scatter/gather cases where you've already set things up and you just want to DMA them. But you probably want to do that with a data/control pair of channels rather than dedicate one channel per buffer.

But it is difficult to design an API that is both safe and flexible. And for full flexibility, it's still possible to configure the DMA registers using the PAC.

Yeah I'm thinking I'll fall back to that to explore the design space and then see if a reasonable safe API makes sense.

Also it doesn't have a way to group channels so you can start them simultaneously.
Can you provide an example where this would be important?

My current project is trying to drive 3 SPI DACs together in lockstep so that the samples are emitted together. The DACs themselves have a PIO SM each which are fully synchronous, but they're triggered by when the first word to output is available.

There's one DMA channel per PIO SM / DAC. Right now manually starting the DMA transfers, there's a noticeable skew across the output steams.

I'd like to start all the DMA transfers simultaneously to minimize the skew. I'm hoping that the SM FIFO buffering will be enough to cover any delayed samples due to things like DMA bus contention (as the DMA is way faster than the PIO clocks).

from rp-hal.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.