-
Notifications
You must be signed in to change notification settings - Fork 51
DAC Improvements - Dual DAC support and DMA #213
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
* Add `DualDac` with simultaneous channel writes, with DMA support * Added `SampleFormat` trait and impls supporting Q1.7, Q1.11, Q1.15 signed and unsigned 8/11b types, left/right alignment * Added `DacTriggerSource` and `DacIncrementSource` traits for selecting external trigger sources with DAC instance constraints * Added DMA support to existing single channel DACs
…amples. Remove ALIGNMENT associated type from SampleFormat
src/dac/format.rs
Outdated
pub struct SampleQ11; | ||
impl SampleFormat for SampleQ11 { | ||
const DEPTH: SampleDepth = SampleDepth::Bits12; | ||
const ALIGNMENT: Alignment = Alignment::Left; |
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.
I have very limited experiance with fixed point formats, but should this really be identical to SampleQ15
?
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.
Well, G4 does claim support for Q1.11 and Q1.15 (1 sign bit, 11 or 15 fractional bits) so I included them both as types, but Q1.15 is a truncation as the DAC only outputs 12 bits and discards the lower 4 bits, and the fixed crate doesn't have sub 16b types (both scalar types are I1F15, hence the same shift and mask). So yes, they are identical.
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.
We use Q15
and Q31
in the CORDIC peripheral as well. Maybe these should be coalesced to avoid repeat definitions?
This is very nice! Do you have any example of using the dual mode or dma that you can share? :) |
I'll try and get an example pushed today. My current codebase depends on some other modifications for CORDIC DMA (which I'll also open PRs for), but I can make something standalone. |
Sounds great! I'll go to sleep now, time zones.. wont be back for a bounch of hours. Thanks so far :) |
Wow! 🤩 I am excited to see that! |
This simple example configures DAC1 in DualDac mode and outputs a wrapping ramp on PA4, and its inverse on PA5 using fixed point Q1.15 format.
I pushed a simple example. I can get a DMA example up at some point - maybe after the CORDIC DMA patches are in and can show an example of CORDIC direct to DAC via DMA. |
Nothing too profound :) but ended up creating a "split DMA", since peripherals like CORDIC/FMAC have both read and write sides, and a Transfer consumes the peripheral, so you can't just impl the necessary traits on the existing struct and have both read and write DMA. Just need to better integrate it so it acts as a singleton with type states (this is what I did with FMAC that I'll be PR'ing shortly) |
Wow, very exciting! :) |
|
||
/// Enable DMA for the specified channel | ||
#[inline(always)] | ||
pub fn enable_dma(&mut self, channel: DacChannel, 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.
Why does DacCh::enable_dma
consume self and turn it into a new type while this one does not?
Also, is it ok to have set_channels
still available after dma has been enabled?
DualDac
with simultaneous channel writes, with DMA supportSampleFormat
trait and impls supporting Q1.7, Q1.11, Q1.15 signed and unsigned 8/11b types, left/right alignmentDacTriggerSource
andDacIncrementSource
traits for selecting external trigger sources with DAC instance constraintsHere's an example of using a circular phase angle buffer which is DMA'd into CORDIC in SinCos mode, with DualDac configured to DMA samples directly from CORDIC RDATA register in Q1.15 format, and triggered by Tim6 at 1MHz. This produces a quadrature output on both DAC1 channels, with zero CPU.