Página 1 de 1

STM DAC DMA

MensagemEnviado: 01 Jun 2018 16:05
por vtrx
Quem ja utilizou o DAC da linha STM32Fxx?

Re: STM DAC DMA

MensagemEnviado: 19 Jan 2019 00:46
por Guri
Olá, vtrx.

Eu já utilizei bastante, qual a dúvida!

No meu caso utilizei o DAC do STM 051, que tem um DAC de 12 bits

Re: STM DAC DMA

MensagemEnviado: 19 Jan 2019 06:53
por vtrx
Olá.
Por enquanto ja não utilizo a rotina que iria usar o DMA.

Re: STM DAC DMA

MensagemEnviado: 21 Jan 2019 09:08
por Guri
Eu tenho aprendido em meus testes, que ao utilizar o DMA para o DAC, em especial via I2S, deve-se prestar a atenção quanto a sinalização de inicio e fim do strem (acho que é assim que se diz), pois o DMA nesse caso não possui buffer duplo.

Apanhei um pouco com isso, mas foi resolvido utilizando-se sinalização por flags dentro da rotina de controle do DAC i2s.

Espero ter ajudado,

Re: STM DAC DMA

MensagemEnviado: 24 Jan 2019 08:43
por cfreund
A linha F0 n tem double buffer.

Nesses casos, costumo trabalhar com dois interrupções: HALF e COMPLETE, tratando metade do buffer em cada situação.

Re: STM DAC DMA

MensagemEnviado: 04 Fev 2019 07:57
por Guri
Olá Claudio,

Explica melhor o método que utiliza para utilizar o DMA ''duplo'', com a interrupção?

Eu fui entender que o DMA para uso com audio, quer seja via DAC interno ou utilizando um DAC serial externo i2s.

No meu caso usei resolução de 16bits no buffer e houve a necessidade de utilizar o DMA para canalizar de forma independente o fluxo do buffer através do DMA, o problema que encontrei na época foi que o DMA do F0 não tinha essa capacidade DUPLA...então usei um sistema de sinalização por flags para indicar o inicio e final da transmissão do conteúdo do buffer via DMA...bom, funcionou! Mas deu um pouco de trabalho por causa da montagem dos sinalizadores.

Por isso te perguntei como você fez isso usando a interrupção...não entendi direito o conceito.

Obrigado pela dica.

Re: STM DAC DMA

MensagemEnviado: 04 Fev 2019 09:47
por cfreund
Se o objetivo do double buffer é ler/escrever no buffer sem pausar o DMA:

Código: Selecionar todos
#define DAC_BUFFER_SIZE      256

static uint16_t dac_dma_buffer[DAC_BUFFER_SIZE * 2];

void dac_buffer_feed(uint16_t *dst, uint16_t len)
{
   for (; len; --len)
      *dst++ = new_value;
}

void dma_start()
{
   for (; (DMA1_Channel3->CCR & DMA_CCR_EN); DMA1_Channel3->CCR = 0);
   
   DMA1_Channel3->CPAR  = (uint32_t)&DAC->DAC_DHR12RD;
   DMA1_Channel3->CMAR  = (uint32_t)dac_dma_buffer;
   DMA1_Channel3->CNDTR = (sizeof(dac_dma_buffer) / sizeof(dac_dma_buffer[0]));
   DMA1_Channel3->CCR   = (DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_DIR | DMA_CCR_TEIE | DMA_CCR_HTIE | DMA_CCR_TCIE);
   DMA1_Channel3->CCR  |= (DMA_CCR_EN);
   
   NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}

void DMA1_Channel3_IRQHandler()
{
   register unsigned int isr = DMA1->ISR;
   
   DMA1->IFCR = (DMA_IFCR_CTEIF1 | DMA_IFCR_CHTIF1 | DMA_IFCR_CTCIF1 | DMA_IFCR_CGIF1);
   
   if (isr & DMA_ISR_TEIF1)
   {
      
   }
   
   if (isr & DMA_ISR_HTIF1)   // HALF
   {
      dac_buffer_feed(dac_dma_buffer, DAC_BUFFER_SIZE);
   }
   else if (isr & DMA_ISR_TCIF1)   // COMPLETE
   {
      dac_buffer_feed(dac_dma_buffer + DAC_BUFFER_SIZE, DAC_BUFFER_SIZE);
   }
}


E otimizar bem o tempo gasto na função dac_buffer_feed(), para não ser atropelado pelo DMA.