<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic DMA Ping-Pong DAC Output in LPC Microcontrollers</title>
    <link>https://community.nxp.com/t5/LPC-Microcontrollers/DMA-Ping-Pong-DAC-Output/m-p/518534#M2729</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;STRONG&gt;Content originally posted in LPCWare by lsimons on Wed May 07 12:48:58 MST 2014&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN&gt;I am trying to output procedurally generated audio using the GPDMA and the DAC in a ping-pong transfer scheme.&amp;nbsp; To do this, I've created to linked list items and configured DMA Ch. 0 to output them:&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;dac_transfer_a - Source dac_buffer_a, Next item dac_transfer_b&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;dac_transfer_b - Source dac_buffer_b, Next item dac_transfer_a&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I can set the contents of the dac_buffers before enabling the DMA, and I can see the expected voltages at the DAC.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;In order to update the DAC buffers, I've enabled the Terminal Count Interrupt, and determine which buffer is free by looking at the next linked list item.&amp;nbsp; I thought that since I have just finished transfering, the buffer for the next linked item (DMACCLLI) is busy, and the current transfer's buffer is available.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD bgcolor="#cacaca"&gt; &lt;PRE&gt;
void DMA_IRQHandler() {
uint32_t* free_dac_buffer;

if (LPC_GPDMA-&amp;gt;DMACIntTCStat &amp;amp; (1&amp;lt;&amp;lt;0)) {

if (LPC_GPDMACH0-&amp;gt;DMACCLLI == &amp;amp;dac_transfer_a) {
free_dac_buffer = dac_buffer_b;
} else {
free_dac_buffer = dac_buffer_a;
}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; update_buffer(free_dac_buffer);

LPC_GPDMA-&amp;gt;DMACIntTCClear = 1 &amp;lt;&amp;lt; 0;
}
}
&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;However, I realized I'm assuming that DMACCLLI points at the transfer just completed, and is not immediatly advanced.&amp;nbsp; I couldn't find anything definitive in the datasheet, and was hoping to get confirmation on the right way to handle this kind of transfer.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Thank you,&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;Louis&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Wed, 15 Jun 2016 17:35:12 GMT</pubDate>
    <dc:creator>lpcware</dc:creator>
    <dc:date>2016-06-15T17:35:12Z</dc:date>
    <item>
      <title>DMA Ping-Pong DAC Output</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/DMA-Ping-Pong-DAC-Output/m-p/518534#M2729</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;STRONG&gt;Content originally posted in LPCWare by lsimons on Wed May 07 12:48:58 MST 2014&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN&gt;I am trying to output procedurally generated audio using the GPDMA and the DAC in a ping-pong transfer scheme.&amp;nbsp; To do this, I've created to linked list items and configured DMA Ch. 0 to output them:&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;dac_transfer_a - Source dac_buffer_a, Next item dac_transfer_b&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;dac_transfer_b - Source dac_buffer_b, Next item dac_transfer_a&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I can set the contents of the dac_buffers before enabling the DMA, and I can see the expected voltages at the DAC.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;In order to update the DAC buffers, I've enabled the Terminal Count Interrupt, and determine which buffer is free by looking at the next linked list item.&amp;nbsp; I thought that since I have just finished transfering, the buffer for the next linked item (DMACCLLI) is busy, and the current transfer's buffer is available.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD bgcolor="#cacaca"&gt; &lt;PRE&gt;
void DMA_IRQHandler() {
uint32_t* free_dac_buffer;

if (LPC_GPDMA-&amp;gt;DMACIntTCStat &amp;amp; (1&amp;lt;&amp;lt;0)) {

if (LPC_GPDMACH0-&amp;gt;DMACCLLI == &amp;amp;dac_transfer_a) {
free_dac_buffer = dac_buffer_b;
} else {
free_dac_buffer = dac_buffer_a;
}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; update_buffer(free_dac_buffer);

LPC_GPDMA-&amp;gt;DMACIntTCClear = 1 &amp;lt;&amp;lt; 0;
}
}
&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;However, I realized I'm assuming that DMACCLLI points at the transfer just completed, and is not immediatly advanced.&amp;nbsp; I couldn't find anything definitive in the datasheet, and was hoping to get confirmation on the right way to handle this kind of transfer.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Thank you,&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;Louis&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 15 Jun 2016 17:35:12 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/DMA-Ping-Pong-DAC-Output/m-p/518534#M2729</guid>
      <dc:creator>lpcware</dc:creator>
      <dc:date>2016-06-15T17:35:12Z</dc:date>
    </item>
    <item>
      <title>Re: DMA Ping-Pong DAC Output</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/DMA-Ping-Pong-DAC-Output/m-p/518535#M2730</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;STRONG&gt;Content originally posted in LPCWare by lsimons on Thu May 08 06:35:46 MST 2014&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN&gt;I haven't found a way to halt the DMA during emulation breakpoints, but I was able to get a better look at the state of DMACCLLI via setting/clearing a test point.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD bgcolor="#cacaca"&gt; &lt;PRE&gt;
void DMA_IRQHandler() {
uint32_t* free_dac_buffer;

if (LPC_GPDMA-&amp;gt;DMACIntTCStat &amp;amp; (1&amp;lt;&amp;lt;0)) {
// Linked list has already advanced, e.g. if DMACCLLI points at
// dac_transfer_a, it is performing dac_transfer_b, and dac_buffer_a
// is free.
if ((dma_linked_list_t *)LPC_GPDMACH0-&amp;gt;DMACCLLI == &amp;amp;dac_transfer_a) {
free_dac_buffer = dac_buffer_a;
debug_set_tp1();
} else {
free_dac_buffer = dac_buffer_b;
debug_clear_tp1();
}

load_dac_buffer(free_dac_buffer, DAC_BUFFER_LEN);

LPC_GPDMA-&amp;gt;DMACIntTCClear = 1 &amp;lt;&amp;lt; 0;
}
}
&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;By hard-coding two distinct waveforms into dac_buffer_a and dac_buffer_b, I'm fairly confident that DMACCLLI has already advanced to the next linked item, i.e. it is no longer in the same state it was prior to the interrupt.&amp;nbsp; On the scope, I can see that when TP1 is set, dac_buffer_b is being transferred.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I'm still hoping for a confirmation on this behavior, because I'd hate for a race condition or some other ambiguous timing lead to modifying a buffer that's in use.&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 15 Jun 2016 17:35:13 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/DMA-Ping-Pong-DAC-Output/m-p/518535#M2730</guid>
      <dc:creator>lpcware</dc:creator>
      <dc:date>2016-06-15T17:35:13Z</dc:date>
    </item>
  </channel>
</rss>

