1pub trait PwmDutySink {
3 fn set_duty(&mut self, duty: u16);
4}
5
6impl<F: FnMut(u16)> PwmDutySink for F {
7 fn set_duty(&mut self, duty: u16) {
8 self(duty);
9 }
10}
11
12#[inline]
14pub fn tick_into<S: PwmDutySink, const N: usize>(
15 engine: &mut crate::AudioEngine<'_, N>,
16 sink: &mut S,
17) -> u16 {
18 let duty = engine.tick();
19 sink.set_duty(duty);
20 duty
21}
22
23pub fn fill_buffer_into<S: PwmDutySink, const N: usize>(
25 engine: &mut crate::AudioEngine<'_, N>,
26 buf: &mut [u16],
27 sink: &mut S,
28) -> usize {
29 let n = engine.fill_duty_buffer(buf);
30 if let Some(&duty) = buf.last() {
31 sink.set_duty(duty);
32 }
33 n
34}
35
36pub fn fill_dma_half_buffers<const N: usize>(
38 engine: &mut crate::AudioEngine<'_, N>,
39 half_buf: &mut [u16],
40) -> usize {
41 engine.fill_duty_buffer(half_buf)
42}
43
44#[derive(Debug, PartialEq, Eq)]
46pub struct DutyBuffer<'a> {
47 pub buf: &'a mut [u16],
48 pub cursor: usize,
49}
50
51impl<'a> DutyBuffer<'a> {
52 pub const fn new(buf: &'a mut [u16]) -> Self {
53 Self { buf, cursor: 0 }
54 }
55}
56
57impl PwmDutySink for DutyBuffer<'_> {
58 fn set_duty(&mut self, duty: u16) {
59 if self.cursor < self.buf.len() {
60 self.buf[self.cursor] = duty;
61 self.cursor += 1;
62 }
63 }
64}
65
66#[derive(Debug, Clone)]
71pub struct DmaDoubleBuffer<T, const N: usize> {
72 buffer: [[T; N]; 2],
73 active_half: usize,
74}
75
76impl<T: Copy + Default, const N: usize> DmaDoubleBuffer<T, N> {
77 pub const HALF_SIZE: usize = N;
78 pub const TOTAL_SIZE: usize = N * 2;
79
80 pub fn new() -> Self {
81 Self {
82 buffer: [[T::default(); N]; 2],
83 active_half: 0,
84 }
85 }
86
87 pub const fn from_buffers(buf0: [T; N], buf1: [T; N]) -> Self {
88 Self {
89 buffer: [buf0, buf1],
90 active_half: 0,
91 }
92 }
93
94 pub fn buffers(&self) -> &[[T; N]; 2] {
96 &self.buffer
97 }
98
99 pub fn buffers_mut(&mut self) -> &mut [[T; N]; 2] {
101 &mut self.buffer
102 }
103
104 pub fn current_half_mut(&mut self) -> &mut [T; N] {
106 &mut self.buffer[self.active_half]
107 }
108
109 pub fn current_half(&self) -> &[T; N] {
111 &self.buffer[self.active_half]
112 }
113
114 pub fn swap_and_get_next(&mut self) -> &mut [T; N] {
116 self.active_half ^= 1;
117 self.current_half_mut()
118 }
119
120 pub fn fill_and_swap<F>(&mut self, mut fill_fn: F) -> &mut [T; N]
122 where
123 F: FnMut(&mut [T; N]),
124 {
125 let next_half = self.active_half ^ 1;
126 fill_fn(&mut self.buffer[next_half]);
127 self.active_half = next_half;
128 &mut self.buffer[next_half]
129 }
130}
131
132impl<T: Copy + Default, const N: usize> Default for DmaDoubleBuffer<T, N> {
133 fn default() -> Self {
134 Self::new()
135 }
136}