@@ -32,16 +32,17 @@ struct dac_descr_t {
3232 uint32_t dmaudr_flag;
3333 DMAPool<Sample> *pool;
3434 DMABuffer<Sample> *dmabuf[2 ];
35+ bool loop_mode;
3536};
3637
3738// NOTE: Both DAC channel descriptors share the same DAC handle.
3839static DAC_HandleTypeDef dac = {0 };
3940
4041static dac_descr_t dac_descr_all[] = {
4142 {&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 },
4344 {&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 },
4546};
4647
4748static uint32_t DAC_RES_LUT[] = {
@@ -110,7 +111,7 @@ bool AdvancedDAC::available() {
110111
111112DMABuffer<Sample> &AdvancedDAC::dequeue () {
112113 static DMABuffer<Sample> NULLBUF;
113- if (descr != nullptr ) {
114+ if (descr != nullptr && !descr-> loop_mode ) {
114115 while (!available ()) {
115116 __WFI ();
116117 }
@@ -130,7 +131,9 @@ void AdvancedDAC::write(DMABuffer<Sample> &dmabuf) {
130131 dmabuf.flush ();
131132 dmabuf.release ();
132133
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 )))) {
134137 descr->dmabuf [0 ] = descr->pool ->alloc (DMA_BUFFER_READ);
135138 descr->dmabuf [1 ] = descr->pool ->alloc (DMA_BUFFER_READ);
136139
@@ -148,7 +151,7 @@ void AdvancedDAC::write(DMABuffer<Sample> &dmabuf) {
148151 }
149152}
150153
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 ) {
152155 // Sanity checks.
153156 if (resolution >= AN_ARRAY_SIZE (DAC_RES_LUT) || descr != nullptr ) {
154157 return 0 ;
@@ -172,6 +175,8 @@ int AdvancedDAC::begin(uint32_t resolution, uint32_t frequency, size_t n_samples
172175 descr = nullptr ;
173176 return 0 ;
174177 }
178+
179+ descr->loop_mode = loop;
175180 descr->resolution = DAC_RES_LUT[resolution];
176181
177182 // Init and config DMA.
@@ -192,26 +197,23 @@ int AdvancedDAC::begin(uint32_t resolution, uint32_t frequency, size_t n_samples
192197 return 1 ;
193198}
194199
195- int AdvancedDAC::stop ()
196- {
200+ int AdvancedDAC::stop () {
197201 if (descr != nullptr ) {
198202 dac_descr_deinit (descr, true );
199203 descr = nullptr ;
200204 }
201205 return 1 ;
202206}
203207
204- int AdvancedDAC::frequency (uint32_t const frequency)
205- {
208+ int AdvancedDAC::frequency (uint32_t const frequency) {
206209 if (descr != nullptr ) {
207210 // Reconfigure the trigger timer.
208211 dac_descr_deinit (descr, false );
209212 hal_tim_config (&descr->tim , frequency);
210213 }
211214}
212215
213- AdvancedDAC::~AdvancedDAC ()
214- {
216+ AdvancedDAC::~AdvancedDAC () {
215217 dac_descr_deinit (descr, true );
216218}
217219
@@ -227,6 +229,10 @@ void DAC_DMAConvCplt(DMA_HandleTypeDef *dma, uint32_t channel) {
227229 size_t ct = ! hal_dma_get_ct (dma);
228230 descr->dmabuf [ct]->release ();
229231 descr->dmabuf [ct] = descr->pool ->alloc (DMA_BUFFER_READ);
232+ if (descr->loop_mode ) {
233+ // Move a buffer from the write queue to the read queue.
234+ descr->pool ->alloc (DMA_BUFFER_WRITE)->release ();
235+ }
230236 hal_dma_update_memory (dma, descr->dmabuf [ct]->data ());
231237 } else {
232238 dac_descr_deinit (descr, false );
0 commit comments