-
Notifications
You must be signed in to change notification settings - Fork 201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DMA-enabled embedded-hal
blocking implementations
#772
Open
jbeaurivage
wants to merge
7
commits into
atsamd-rs:master
Choose a base branch
from
jbeaurivage:spi-dma
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 tasks
jbeaurivage
force-pushed
the
spi-dma
branch
3 times, most recently
from
October 24, 2024 02:44
37c34ee
to
eba50e1
Compare
jbeaurivage
force-pushed
the
spi-dma
branch
5 times, most recently
from
October 25, 2024 14:20
89203a7
to
8b6a0dd
Compare
jbeaurivage
force-pushed
the
spi-dma
branch
6 times, most recently
from
October 28, 2024 16:44
776822b
to
7b66222
Compare
* Add full support for SPI transfers using DMA and the `embedded_hal::spi::SpiBus` trait * Deprecate `Spi::send_with_dma` and `Spi::receive_with_dma`
* Add full support for I2C transfers using DMA and the `embedded_hal::i2c::I2c` trait * Deprecate `I2c::send_with_dma` and `I2c::receive_with_dma`
* Add full support for UART transfers using DMA and the `embedded_io::Write` and `embedded_io::Read` traits
2 tasks
kyp44
pushed a commit
to kyp44/kuboble-rs
that referenced
this pull request
Nov 1, 2024
…raphics, which depend on a PR being merged: atsamd-rs/atsamd#772
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Context
SPI timing and performance issues
In #657, @Felix-El has pointed out that the blocking SPI implementations were somewhat fragile and prone to race conditions. @ianrrees also had some similar comments in #751. Essentially, our SPI transfers are done word by word, which might:
SPI transfers using DMA
Currently, the HAL has minimal support for making SPI transfers using DMA. It exposes the
send_with_dma
andreceive_with_dma
methods. However these:'static
buffers in order to satisfy memory safety invariants (namely, due to point 1)embedded-hal::spi::SpiBus
trait implementations.The same points are also true for our UART and I2C drivers.
Proposal
In this PR, I suggest a new implementation to make DMA-enabled SPI transfers. It provides blocking, safe implementations that don't need to take
'static
buffers. The API to use DMA is as simple as configuring 2 DMA channels, then callingSpi::with_dma_channels
, and all subsequent transfers will use DMA.What I propose is that we encourage users who have strict timing or performance requirements, or need very high frequency transfers, to use the DMA implementations. The word-by-word implementation can therefore remain simple, without the need for us to expend lots of energy trying to optimize it for performance. Users with loose timings or lower frequencies can still use it with reduced configuration complexity (which is really not a lot).
The rationale is that we can probably optimize the word-by-word implementation a bit, but we'll soon hit an upper limit, which we can only exceed using DMA anyways. DMA transfers are also impervious to preemption by higher priority interrupts.
I want to add the same mechanisms for I2C and UART, since most of the effort is already done and reusable there.
What's included
send_with_dma
andreceive_with_dma
methods as deprecated. They should be removed either in this PR or in a subsequent release -- perhaps at the same time as the ehal 0.2 stuff. Keep the UARTsend_with_dma
andreceive_with_dma
nonblocking methods, as they can be used on a split UART to do some interesting things.Configurable NOP word for SPI transfersTurns out this was already implementedSPI-specific improvements
Spi
implementation relies on fragile timing #657 (see comment).What's not included
embedded-hal-nb
DMA implementations. These would either require the user to pass'static
buffers everywhere, or require all DMA-enabled methods to be unsafe. Both options are incompatible with the traitsembedded-hal-nb
provides. For non-blocking concurrent code, I would strongly suggest users look at async instead (Async API #635).There have also been reports of fragile timing and performance in our blocking
embedded-hal v0.2
implementations. I'm not particularly interested in updating those. In fact, I would like to remove embedded-hal v0.2 from atsamd-hal entirely (perhaps in another PR).Breaking changes
Checklist
#[allow]
certain lints where reasonable, but ideally justify those with a short comment.Notes for reviewers:
This PR is built on top of fix: Changes to the
dmac
public API #764, which should be merged first.Please merge this PR using rebase (and not squash) to conserve changelog history.
Closes #657.