-
Notifications
You must be signed in to change notification settings - Fork 51
Add FMAC implementation #214
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
base: main
Are you sure you want to change the base?
Conversation
|
||
/// Enable write DMA to the WDATA register | ||
#[inline(always)] | ||
pub fn enable_write_dma(&mut self, enable: bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this relate to acquire_dma
and start_dma
? Why is it available in non-dma modes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The enable_x_dma()
are to set the enable DMA bits in the peripheral.
acquire_dma()
returns a tuple of:
Fmac
inStoppedDma
state which exposesstart_dma()
to start the FMAC- an
FmacDmaReader
which can be consumed by a transfer, and - an
FmacDmaWriter
which can be consumed by another transfer.
The Fmac handle in StoppedDma can then start the FMAC after DMA has been configured by calling start_dma()
which is only exposed in StoppedDma
state.
So if you just want say write DMA, it would be something like
let fmac = Fmac::constrain<BufferLayout<8,8,8>>(&mut rcc);
// Acquire split DMA read/write handles - discarding the read handle.
let (fmac, _, write_dma) = fmac.acquire_dma();
// Tell FMAC to generate write DMA requests
fmac.enable_write_dma();
// Give the DMA write handle to a transfer
let transfer = dma_ch.into_memory_to_peripheral_transfer(write_dma, ...);
// Now start the FMAC
fmac.start_dma();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks, that makes sense. So the peripheral is still useful for non-dma use if the user so chooses? As in this case the user can still read from the fmac and only use the dma for writing?
I assume there is nothing preventing the user from writing the fmac at the same time as the dma is enabled. Are there any risks with that?
Very cool! :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! Just one comment from me.
I have never used the FMAC so I can't verify that the hardware invariances are exhaustively upheld by this implementation.
@@ -17,7 +17,7 @@ stm32g4 = { version = "0.16.0", features = ["atomics"] } | |||
paste = "1.0" | |||
fugit = "0.3.7" | |||
stm32-usbd = { version = "0.7.0", optional = true } | |||
fixed = { version = "1.28.0", optional = true } | |||
fixed = { version = "1.28.0" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why make this no longer optional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually originated from DualDac PR, which wasn't feature gated and depends on fixed::types
- not strictly necessary for this PR, but if DualDac is merged as-is, it wouldn't be optional. Could either feature gate dualdac or just leave this as is
cordic = [] | ||
fmac = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cordic = [] | |
fmac = [] | |
cordic = ["dep:fixed"] | |
fmac = ["dep:fixed"] |
Yes, only tested so far on G474VET6. I have some 474CET and RET, and G431s I can test on when I find some cycles. |
// Y[n] = ∑ X1[n] * X2[0] + Y[n-1] * X2[1] | ||
// | ||
// The inputs will be set to ~0.01 (to nearest fixed point representation), and the output will increment | ||
// by 0.01 into Y for each input sample, and the final read of Y should be about 0.319 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The `SysCfg` peripheral used bit banding to set the APB2 peripheral clock enable bit which fails on an assertion on a G431KBT (have not tested on other chips, but I suspect they would do the same). This takes a mutable reference to `Rcc` in `SysCfg::constrain` and uses safe accessors to enable the clock. Updated and tested the button example which is all that uses SysCfg. ```[INFO ] Configuring PLL (stm32_foc stm32-foc/src/main.rs:132) [INFO ] System clock frequency: 168000000 (stm32_foc stm32-foc/src/main.rs:138) [DEBUG] Write 20007FB0 (stm32g4xx_hal stm32g4xx-hal/src/bb.rs:42) [ERROR] panicked at /Users/fuzz/wave/stm32g4xx-hal/src/bb.rs:44:5: assertion failed: (PERI_ADDRESS_START..=PERI_ADDRESS_END).contains(&addr) (panic_probe panic-probe-1.0.0/src/lib.rs:104) Firmware exited unexpectedly: Multiple Core 0 Frame 0: HardFault_ @ 0x08006394 /Users/fuzz/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cortex-m-rt-0.7.5/src/lib.rs:1103:1 Frame 1: HardFault <Cause: Escalated UsageFault <Cause: Undefined instruction>> @ 0x08005ce2```
feat: Add FMAC support for digital signal processing Implement support for the STM32G4's Filter Math Accelerator (FMAC) peripheral, which provides hardware acceleration for digital signal processing operations including: - FIR filter implementation - IIR filter implementation (direct form 1) - Vector operations such as dot products The implementation includes: - Core FMAC peripheral control - Type states to constrain method access - Buffer management with const generic configurable layouts - DMA support for efficient data transfer
Co-authored-by: Albin Hedman <[email protected]>
feat: Add FMAC support for digital signal processing
Implement support for the STM32G4's Filter Math Accelerator (FMAC) peripheral, which provides hardware acceleration for digital signal processing operations including:
The implementation includes: