@@ -32,16 +32,17 @@ struct dac_descr_t {
32
32
uint32_t dmaudr_flag;
33
33
DMAPool<Sample> *pool;
34
34
DMABuffer<Sample> *dmabuf[2 ];
35
+ bool loop_mode;
35
36
};
36
37
37
38
// NOTE: Both DAC channel descriptors share the same DAC handle.
38
39
static DAC_HandleTypeDef dac = {0 };
39
40
40
41
static dac_descr_t dac_descr_all[] = {
41
42
{&dac, DAC_CHANNEL_1, {DMA1_Stream4, {DMA_REQUEST_DAC1_CH1}}, DMA1_Stream4_IRQn, {TIM4},
42
- DAC_TRIGGER_T4_TRGO, DAC_ALIGN_12B_R, DAC_FLAG_DMAUDR1, nullptr , {nullptr , nullptr }},
43
+ DAC_TRIGGER_T4_TRGO, DAC_ALIGN_12B_R, DAC_FLAG_DMAUDR1, nullptr , {nullptr , nullptr }, false },
43
44
{&dac, DAC_CHANNEL_2, {DMA1_Stream5, {DMA_REQUEST_DAC1_CH2}}, DMA1_Stream5_IRQn, {TIM5},
44
- DAC_TRIGGER_T5_TRGO, DAC_ALIGN_12B_R, DAC_FLAG_DMAUDR2, nullptr , {nullptr , nullptr }},
45
+ DAC_TRIGGER_T5_TRGO, DAC_ALIGN_12B_R, DAC_FLAG_DMAUDR2, nullptr , {nullptr , nullptr }, false },
45
46
};
46
47
47
48
static uint32_t DAC_RES_LUT[] = {
@@ -110,7 +111,7 @@ bool AdvancedDAC::available() {
110
111
111
112
DMABuffer<Sample> &AdvancedDAC::dequeue () {
112
113
static DMABuffer<Sample> NULLBUF;
113
- if (descr != nullptr ) {
114
+ if (descr != nullptr && !descr-> loop_mode ) {
114
115
while (!available ()) {
115
116
__WFI ();
116
117
}
@@ -130,7 +131,9 @@ void AdvancedDAC::write(DMABuffer<Sample> &dmabuf) {
130
131
dmabuf.flush ();
131
132
dmabuf.release ();
132
133
133
- if (descr->dmabuf [0 ] == nullptr && (++buf_count % 3 ) == 0 ) {
134
+ if (!descr->dmabuf [0 ] &&
135
+ ((descr->loop_mode && !descr->pool ->writable ()) ||
136
+ (!descr->loop_mode && (++buf_count % 3 == 0 )))) {
134
137
descr->dmabuf [0 ] = descr->pool ->alloc (DMA_BUFFER_READ);
135
138
descr->dmabuf [1 ] = descr->pool ->alloc (DMA_BUFFER_READ);
136
139
@@ -148,7 +151,7 @@ void AdvancedDAC::write(DMABuffer<Sample> &dmabuf) {
148
151
}
149
152
}
150
153
151
- int AdvancedDAC::begin (uint32_t resolution, uint32_t frequency, size_t n_samples, size_t n_buffers) {
154
+ int AdvancedDAC::begin (uint32_t resolution, uint32_t frequency, size_t n_samples, size_t n_buffers, bool loop ) {
152
155
// Sanity checks.
153
156
if (resolution >= AN_ARRAY_SIZE (DAC_RES_LUT) || descr != nullptr ) {
154
157
return 0 ;
@@ -172,6 +175,9 @@ int AdvancedDAC::begin(uint32_t resolution, uint32_t frequency, size_t n_samples
172
175
descr = nullptr ;
173
176
return 0 ;
174
177
}
178
+
179
+ descr->loop_mode = loop;
180
+ n_buffers = n_buffers;
175
181
descr->resolution = DAC_RES_LUT[resolution];
176
182
177
183
// Init and config DMA.
@@ -192,26 +198,23 @@ int AdvancedDAC::begin(uint32_t resolution, uint32_t frequency, size_t n_samples
192
198
return 1 ;
193
199
}
194
200
195
- int AdvancedDAC::stop ()
196
- {
201
+ int AdvancedDAC::stop () {
197
202
if (descr != nullptr ) {
198
203
dac_descr_deinit (descr, true );
199
204
descr = nullptr ;
200
205
}
201
206
return 1 ;
202
207
}
203
208
204
- int AdvancedDAC::frequency (uint32_t const frequency)
205
- {
209
+ int AdvancedDAC::frequency (uint32_t const frequency) {
206
210
if (descr != nullptr ) {
207
211
// Reconfigure the trigger timer.
208
212
dac_descr_deinit (descr, false );
209
213
hal_tim_config (&descr->tim , frequency);
210
214
}
211
215
}
212
216
213
- AdvancedDAC::~AdvancedDAC ()
214
- {
217
+ AdvancedDAC::~AdvancedDAC () {
215
218
dac_descr_deinit (descr, true );
216
219
}
217
220
@@ -227,6 +230,10 @@ void DAC_DMAConvCplt(DMA_HandleTypeDef *dma, uint32_t channel) {
227
230
size_t ct = ! hal_dma_get_ct (dma);
228
231
descr->dmabuf [ct]->release ();
229
232
descr->dmabuf [ct] = descr->pool ->alloc (DMA_BUFFER_READ);
233
+ if (descr->loop_mode ) {
234
+ // Move a buffer from the write queue to the read queue.
235
+ descr->pool ->alloc (DMA_BUFFER_WRITE)->release ();
236
+ }
230
237
hal_dma_update_memory (dma, descr->dmabuf [ct]->data ());
231
238
} else {
232
239
dac_descr_deinit (descr, false );
0 commit comments