Skip to content

Commit 432570f

Browse files
committed
AdvancedDAC: Add support for loop mode.
Loop mode starts the DAC automatically when all buffers in the queue are written. Once started, the DAC will continuously cycle through all of the buffers in the queue. Signed-off-by: iabdalkader <[email protected]>
1 parent 70a630e commit 432570f

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

src/AdvancedDAC.cpp

+18-11
Original file line numberDiff line numberDiff line change
@@ -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.
3839
static DAC_HandleTypeDef dac = {0};
3940

4041
static 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

4748
static uint32_t DAC_RES_LUT[] = {
@@ -110,7 +111,7 @@ bool AdvancedDAC::available() {
110111

111112
DMABuffer<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,9 @@ 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;
180+
n_buffers = n_buffers;
175181
descr->resolution = DAC_RES_LUT[resolution];
176182

177183
// Init and config DMA.
@@ -192,26 +198,23 @@ int AdvancedDAC::begin(uint32_t resolution, uint32_t frequency, size_t n_samples
192198
return 1;
193199
}
194200

195-
int AdvancedDAC::stop()
196-
{
201+
int AdvancedDAC::stop() {
197202
if (descr != nullptr) {
198203
dac_descr_deinit(descr, true);
199204
descr = nullptr;
200205
}
201206
return 1;
202207
}
203208

204-
int AdvancedDAC::frequency(uint32_t const frequency)
205-
{
209+
int AdvancedDAC::frequency(uint32_t const frequency) {
206210
if (descr != nullptr) {
207211
// Reconfigure the trigger timer.
208212
dac_descr_deinit(descr, false);
209213
hal_tim_config(&descr->tim, frequency);
210214
}
211215
}
212216

213-
AdvancedDAC::~AdvancedDAC()
214-
{
217+
AdvancedDAC::~AdvancedDAC() {
215218
dac_descr_deinit(descr, true);
216219
}
217220

@@ -227,6 +230,10 @@ void DAC_DMAConvCplt(DMA_HandleTypeDef *dma, uint32_t channel) {
227230
size_t ct = ! hal_dma_get_ct(dma);
228231
descr->dmabuf[ct]->release();
229232
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+
}
230237
hal_dma_update_memory(dma, descr->dmabuf[ct]->data());
231238
} else {
232239
dac_descr_deinit(descr, false);

src/AdvancedDAC.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class AdvancedDAC {
4545
bool available();
4646
SampleBuffer dequeue();
4747
void write(SampleBuffer dmabuf);
48-
int begin(uint32_t resolution, uint32_t frequency, size_t n_samples=0, size_t n_buffers=0);
48+
int begin(uint32_t resolution, uint32_t frequency, size_t n_samples=0, size_t n_buffers=0, bool loop=false);
4949
int stop();
5050
int frequency(uint32_t const frequency);
5151
};

0 commit comments

Comments
 (0)