@@ -29,6 +29,7 @@ struct dac_descr_t {
2929    TIM_HandleTypeDef tim;
3030    uint32_t  tim_trig;
3131    uint32_t  resolution;
32+     uint32_t  dmaudr_flag;
3233    DMABufferPool<Sample> *pool;
3334    DMABuffer<Sample> *dmabuf[2 ];
3435};
@@ -37,10 +38,10 @@ struct dac_descr_t {
3738static  DAC_HandleTypeDef dac = {0 };
3839
3940static  dac_descr_t  dac_descr_all[] = {
40-     {&dac, DAC_CHANNEL_1, {DMA1_Stream4, {DMA_REQUEST_DAC1_CH1}}, DMA1_Stream4_IRQn,
41-         {TIM4},  DAC_TRIGGER_T4_TRGO, DAC_ALIGN_12B_R, nullptr , {nullptr , nullptr }},
42-     {&dac, DAC_CHANNEL_2, {DMA1_Stream5, {DMA_REQUEST_DAC1_CH2}}, DMA1_Stream5_IRQn,
43-         {TIM5},  DAC_TRIGGER_T5_TRGO, DAC_ALIGN_12B_R, nullptr , {nullptr , nullptr }},
41+     {&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, 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 }},
4445};
4546
4647static  uint32_t  DAC_RES_LUT[] = {
@@ -73,10 +74,12 @@ static dac_descr_t *dac_descr_get(uint32_t channel) {
7374}
7475
7576static  void  dac_descr_deinit (dac_descr_t  *descr, bool  dealloc_pool) {
76-     if  (descr) {
77+     if  (descr !=  nullptr ) {
7778        HAL_TIM_Base_Stop (&descr->tim );
7879        HAL_DAC_Stop_DMA (descr->dac , descr->channel );
7980
81+         __HAL_DAC_CLEAR_FLAG (descr->dac , descr->dmaudr_flag );
82+ 
8083        for  (size_t  i=0 ; i<AN_ARRAY_SIZE (descr->dmabuf ); i++) {
8184            if  (descr->dmabuf [i]) {
8285                descr->dmabuf [i]->release ();
@@ -89,13 +92,17 @@ static void dac_descr_deinit(dac_descr_t *descr, bool dealloc_pool) {
8992                delete  descr->pool ;
9093            }
9194            descr->pool  = nullptr ;
95+         } else  {
96+             descr->pool ->flush ();
9297        }
93- 
9498    }
9599}
96100
97101bool  AdvancedDAC::available () {
98102    if  (descr != nullptr ) {
103+         if  (__HAL_DAC_GET_FLAG (descr->dac , descr->dmaudr_flag )) {
104+             dac_descr_deinit (descr, false );
105+         }
99106        return  descr->pool ->writable ();
100107    }
101108    return  false ;
@@ -113,11 +120,17 @@ DMABuffer<Sample> &AdvancedDAC::dequeue() {
113120}
114121
115122void  AdvancedDAC::write (DMABuffer<Sample> &dmabuf) {
123+     static  uint32_t  buf_count = 0 ;
124+ 
125+     if  (descr == nullptr ) {
126+         return ;
127+     }
128+ 
116129    //  Make sure any cached data is flushed.
117130    dmabuf.flush ();
118131    descr->pool ->enqueue (&dmabuf);
119132
120-     if  (descr->dmabuf [0 ] == nullptr  && descr-> pool -> readable () >  2 ) {
133+     if  (descr->dmabuf [0 ] == nullptr  && (++buf_count %  3 ) ==  0 ) {
121134        descr->dmabuf [0 ] = descr->pool ->dequeue ();
122135        descr->dmabuf [1 ] = descr->pool ->dequeue ();
123136
@@ -126,7 +139,9 @@ void AdvancedDAC::write(DMABuffer<Sample> &dmabuf) {
126139        (uint32_t  *) descr->dmabuf [0 ]->data (), descr->dmabuf [0 ]->size (), descr->resolution );
127140
128141        //  Re/enable DMA double buffer mode.
142+         HAL_NVIC_DisableIRQ (descr->dma_irqn );
129143        hal_dma_enable_dbm (&descr->dma , descr->dmabuf [0 ]->data (), descr->dmabuf [1 ]->data ());
144+         HAL_NVIC_EnableIRQ (descr->dma_irqn );
130145
131146        //  Start trigger timer.
132147        HAL_TIM_Base_Start (&descr->tim );
@@ -135,7 +150,7 @@ void AdvancedDAC::write(DMABuffer<Sample> &dmabuf) {
135150
136151int  AdvancedDAC::begin (uint32_t  resolution, uint32_t  frequency, size_t  n_samples, size_t  n_buffers) {
137152    //  Sanity checks.
138-     if  (resolution >= AN_ARRAY_SIZE (DAC_RES_LUT) || ( descr && descr-> pool ) ) {
153+     if  (resolution >= AN_ARRAY_SIZE (DAC_RES_LUT) || descr !=  nullptr ) {
139154        return  0 ;
140155    }
141156
@@ -147,13 +162,14 @@ int AdvancedDAC::begin(uint32_t resolution, uint32_t frequency, size_t n_samples
147162
148163    uint32_t  function = pinmap_function (dac_pins[0 ], PinMap_DAC);
149164    descr = dac_descr_get (DAC_CHAN_LUT[STM_PIN_CHANNEL (function) - 1 ]);
150-     if  (descr == nullptr  || descr-> pool ) {
165+     if  (descr == nullptr ) {
151166        return  0 ;
152167    }
153168
154169    //  Allocate DMA buffer pool.
155170    descr->pool  = new  DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
156171    if  (descr->pool  == nullptr ) {
172+         descr = nullptr ;
157173        return  0 ;
158174    }
159175    descr->resolution  = DAC_RES_LUT[resolution];
@@ -178,13 +194,16 @@ int AdvancedDAC::begin(uint32_t resolution, uint32_t frequency, size_t n_samples
178194
179195int  AdvancedDAC::stop ()
180196{
181-     dac_descr_deinit (descr, true );
197+     if  (descr != nullptr ) {
198+         dac_descr_deinit (descr, true );
199+         descr = nullptr ;
200+     }
182201    return  1 ;
183202}
184203
185204int  AdvancedDAC::frequency (uint32_t  const  frequency)
186205{
187-     if  (descr && descr-> pool ) {
206+     if  (descr !=  nullptr ) {
188207        //  Reconfigure the trigger timer.
189208        dac_descr_deinit (descr, false );
190209        hal_tim_config (&descr->tim , frequency);
@@ -200,9 +219,10 @@ extern "C" {
200219
201220void  DAC_DMAConvCplt (DMA_HandleTypeDef *dma, uint32_t  channel) {
202221    dac_descr_t  *descr = dac_descr_get (channel);
222+ 
203223    //  Release the DMA buffer that was just done, allocate a new one,
204224    //  and update the next DMA memory address target.
205-     if  (descr->pool ->readable ()) {
225+     if  (descr && descr ->pool ->readable ()) {
206226        //  NOTE: CT bit is inverted, to get the DMA buffer that's Not currently in use.
207227        size_t  ct = ! hal_dma_get_ct (dma);
208228        descr->dmabuf [ct]->release ();
0 commit comments