Skip to content
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

Runtime DMA interrupt binding #1300

Merged
merged 1 commit into from
Mar 26, 2024

Conversation

bjoernQ
Copy link
Contributor

@bjoernQ bjoernQ commented Mar 15, 2024

This is ready for review now.

Basically, the user-facing change is there is that configure configures the DMA channel for blocking mode while configure_for_async configures the channel for async operation. The async interrupt handler for that channel is only installed when configure_for_async is used.

It's possible to register an interrupt handler for a blocking channel but it's not really useful, yet. However, that wasn't really possible before and is something for a future enhancement. (And would need some new/additional API probably)

@bjoernQ bjoernQ force-pushed the dma-runtime-isr-binding branch from 3c13e7d to ba2519a Compare March 15, 2024 16:09
@bjoernQ bjoernQ added the status:blocked Unable to progress - dependent on another task label Mar 19, 2024
@bjoernQ
Copy link
Contributor Author

bjoernQ commented Mar 19, 2024

blocked by
#1294

#1299

needs
esp-rs/esp-pacs#209

somewhat blocked by #1310

@bjoernQ bjoernQ force-pushed the dma-runtime-isr-binding branch 3 times, most recently from c46a6dc to f724a73 Compare March 21, 2024 16:40
@jessebraham jessebraham removed the status:blocked Unable to progress - dependent on another task label Mar 21, 2024
@jessebraham
Copy link
Member

All blockers have been resolved!

@bjoernQ bjoernQ force-pushed the dma-runtime-isr-binding branch 2 times, most recently from 04bbd56 to c4dea96 Compare March 22, 2024 08:58
@bjoernQ bjoernQ marked this pull request as ready for review March 22, 2024 09:04
Copy link
Contributor

@JurajSadel JurajSadel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

embassy_i2s_read is not working on C6, H2 and S3. For me, it prints only:

Init!
Start

main works fine, though.

@bjoernQ
Copy link
Contributor Author

bjoernQ commented Mar 22, 2024

Blocked again since it will need the proc-macro-changes from #1341

@bjoernQ bjoernQ added the status:blocked Unable to progress - dependent on another task label Mar 22, 2024
@jessebraham jessebraham removed the status:blocked Unable to progress - dependent on another task label Mar 25, 2024
@jessebraham
Copy link
Member

Unblocked again! 😁

@bjoernQ bjoernQ force-pushed the dma-runtime-isr-binding branch from c4dea96 to 7eda2c6 Compare March 25, 2024 14:10
Copy link
Member

@jessebraham jessebraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of changes here but otherwise LGTM, thanks for taking care of this.

One little nitpick, plus still need to address whatever remaining comments from @MabezDev I suppose, then we should probably be good to merge.

@bjoernQ bjoernQ force-pushed the dma-runtime-isr-binding branch from 5a82b6b to 1f56ce7 Compare March 25, 2024 17:05
@bjoernQ
Copy link
Contributor Author

bjoernQ commented Mar 25, 2024

I think I addressed everything? Or did I miss something?

@jessebraham
Copy link
Member

I think that's it, we will need @MabezDev to approve this to merge however.

@jessebraham jessebraham enabled auto-merge March 25, 2024 17:08
Copy link
Member

@MabezDev MabezDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed a couple of other bits, but I have a bigger question (and I'm sorry in advance)

Do we ever plan Dma Channels to be used publically? In my head I feel like they're a an implementation detail for other drivers. We currently only have impls like impl<'d, C> Channel<'d, C, crate::Blocking>, would we ever have impl<'d, C> Channel<'d, C, crate::Async>? I feel like if we were, for example, async memcpy, we still wouldn't use the DMA channels directly but we'd have a AsyncMemcpy driver which took in the channel.

My point is, I think we can maybe avoid a whole bunch of Dma type state and complexity by:

  • Dropping the Mode param for Channel
  • Making set_interrupt_handler public always on Channel
  • Add a new method on Channel called install_async_handler (choose whatever name you like, it will be a pub(crate) function) which the peripheral driver will call to bind the async interrupt (basically what we do now on the configure_async)

It's then up to the driver to install the async handler, and the rest of the API stays as it were now. For instance, SpiDma would get new method(s) with_dma_async, but dma configuration step would stay the same. The result is a SpiDma<_, _, _, crate::Async>, but the dma channel doesn't care, and IMO it shouldn't. The DMA is dumb peripheral that copies bytes from one place to another.

Maybe I'm missing something, please feel free to correct me! and sorry again for delaying this, I just want to make sure we're going down the right path before we commit to converting all the drivers.

@bjoernQ
Copy link
Contributor Author

bjoernQ commented Mar 25, 2024

I think it might be somewhat useful to have control over DMA interrupts as a user. Unfortunately most peripherals need more than them (those have more checks in their "wait" implementation).

Another option would be to have the blocking drivers in charge of that

In any case the current transaction API isn't suitable for that and we would need another set of APIs

@bjoernQ
Copy link
Contributor Author

bjoernQ commented Mar 25, 2024

But for sure: if we agree DMA is "internal" to the HAL that makes things definitely easier. Channels wouldn't need public functions then at all

@MabezDev
Copy link
Member

I think it might be somewhat useful to have control over DMA interrupts as a user. Unfortunately most peripherals need more than them (those have more checks in their "wait" implementation).

I do agree here, and I think we can still allow that. For instance it's possible to bind the DMA interrupt before calling with_dma, and because with_dma doesn't rebind the interrupt it will still work. This might get a bit hairy though, particularly if a user expected their interrupt to run, but they use with_dma_async which rebinds the interrupt. In that case the current code works better.

I think we need to figure out that use case for DMA interrupts. Perhaps it becomes part of the peripheral driver to register the interrupt? I don't know how it will work with all peripherals, but SpiDma, could have method to configure the DMA interrupt - not sure how I feel about this currently.

Copy link
Member

@MabezDev MabezDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's proceed with this for now I think, unless anyone feels like we shouldn't. I think this is a great approach, so thanks for putting in the time to get it working!

I think my previous comments might have been trying to optimize prematurely; we don't currently know all the DMA use cases and I think your solution here is the most flexible going-forward - we can always change our path as we refine our APIs.

@jessebraham jessebraham added this pull request to the merge queue Mar 26, 2024
@MabezDev MabezDev removed this pull request from the merge queue due to a manual request Mar 26, 2024
@MabezDev
Copy link
Member

Removing from the queue just to address the two other comments then this is good to go from my perspective!

@bjoernQ
Copy link
Contributor Author

bjoernQ commented Mar 26, 2024

Let's proceed with this for now I think, unless anyone feels like we shouldn't. I think this is a great approach, so thanks for putting in the time to get it working!

I think my previous comments might have been trying to optimize prematurely; we don't currently know all the DMA use cases and I think your solution here is the most flexible going-forward - we can always change our path as we refine our APIs.

Sounds good to me! Definitely removing the type-state etc. later is much less work than doing it now and then realizing we need it for something and re-adding it 👍

Will address the remaining two comments and rebase this

@jessebraham jessebraham added this pull request to the merge queue Mar 26, 2024
Merged via the queue into esp-rs:main with commit 4077734 Mar 26, 2024
20 checks passed
@bjoernQ bjoernQ deleted the dma-runtime-isr-binding branch November 26, 2024 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants