Skip to content

stm32/dma: Reset all dma channels during soft-reset. #12803

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

Closed

Conversation

andrewleech
Copy link
Contributor

On a work project I'm using a C module to configure and use DMA for timer interactions. The same thing can be done with https://github.com/andrewleech/micropython-stm32-pwm-sine-wave

Once DMA interrupts have been enabled with any channels not used by internal micropython usage, these don't get turned off on soft-reset which leaves them still enabled. If they get triggered, a hard fault occurs as the HAL interrupt tries to access the original definition struct which has now disappeared.

This MR adds an explicit reset of all DMA channels during soft reset to ensure this hard fault cannot occur.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
@dpgeorge
Copy link
Member

If they get triggered, a hard fault occurs as the HAL interrupt tries to access the original definition struct which has now disappeared.

Why have the original structs disappeared?

I think it might be better to allow a user C module to register a deinit hook, to be called when soft reset occurs. Then the user C module can explicitly call dma_deinit() on those channels it wants to close.

Note that some user C modules (or other external C code) may actually want the DMA to continue over a soft reset. Eg a Bluetooth controller that uses DMA for the UART transfer, that doesn't get reset on soft reset.

@andrewleech
Copy link
Contributor Author

In my application, the dma definition stucts are held by micropython objects that are gc alloc'd by runtime code, so these are wiped out over a reset.

Keeping some dma alive for particular use cases is a very good point though.

The suggestion to instead have the ability for C modules to register a de-init hook is far better, I can think of many use cases for this.
That being said, there was a recent discussion on discord similar to this:

Trent: Question about GC inside micropython. If I create a new object type, in C, that has resources which must be deallocated, is the proper way to do to use m_new_obj_with_finaliser() to allocate it and provide a __del__ method for the object?

https://ptb.discord.com/channels/574275045187125269/1012726673709469818/1173760875539206225

Assuming finaliser support is enabled on the port / build, is this an existing suitable way to handle C user module de-init for soft reset?

@dpgeorge
Copy link
Member

Assuming finaliser support is enabled on the port / build, is this an existing suitable way to handle C user module de-init for soft reset?

Yes! gc_sweep_all() is intended to work this way, that it calls all C finalisers on soft reset.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants