<?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>LPC MicrocontrollersのトピックGPDMA + DAC, V2.12</title>
    <link>https://community.nxp.com/t5/LPC-Microcontrollers/GPDMA-DAC-V2-12/m-p/583777#M20922</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;STRONG&gt;Content originally posted in LPCWare by mch0 on Sat Sep 13 15:25:48 MST 2014&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN&gt;Hi,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;when I tried to run the DAC by GPDMA I ran into two problems with the current LPCOpen libraries (2.12). The good news first: Finally all runs as expected. But I think there is room for improvement for an upcoming 2.13 of LPCOpen.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;1. Transfer width&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;The DAC has a 32bit register for the value, all right. However, only the lower halfword contains the value that will be converted, the upper halfword contains static information.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;So when you create a table im memory for DAC output, you would naturally use a table with 16bit entries. &lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;However, in LPCOpen 2.12 the "natural width" for the DAC is looked up as a WORD, i.e. 32 bit.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;These values are predefined in a lookup table in &lt;/SPAN&gt;&lt;I&gt;gpdma_18xx_43cc.c&lt;/I&gt;&lt;SPAN&gt;:&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;/* Optimized Peripheral Source and Destination transfer width (18xx,43xx) */
static const uint8_t GPDMA_LUTPerWid[] = {
...&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I suggest to change the entry for the DAC (third from bottom) from &lt;/SPAN&gt;&lt;I&gt;GPDMA_WIDTH_WORD&lt;/I&gt;&lt;SPAN&gt; to &lt;/SPAN&gt;&lt;I&gt;GPDMA_WIDTH_HALFWORD&lt;/I&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;With that the DMA will write only the lower 16 bits into the DAC value register - works perfectly. This cuts the table space in memory in half. The DMA also uses less bandwith, since the memory read requests are also halved.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;2. GPDMA setup&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;I found it very complicated to set up a linked list transfer, when a peripheral is involved. I am not sure whether I missed the "easy" way, but here it goes.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;When you use linked lists you have to provide the (chain of) LLI descriptors. There is a function to help you prepare one: &lt;/SPAN&gt;&lt;I&gt;Chip_GPDMA_PrepareDescriptor()&lt;/I&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;That's fine, because you don't want to calculate the control word entry yourself.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;But: This function expects a lookup value for a peripheral, if one is used.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;So you don't enter the "real target" but e.g. &lt;/SPAN&gt;&lt;I&gt;GPDMA_CONN_DAC&lt;/I&gt;&lt;SPAN&gt; for the DAC. The function then looks up the target address for you (fine) and uses this value also for other calculations.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;After the call this entry is replaced by the real address (fine again).&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;But after preparing the LLI you have to pass a pointer to it when you prepare the actual transfer with&lt;/SPAN&gt;&lt;BR /&gt;&lt;I&gt;Chip_GPDMA_SGTransfer()&lt;/I&gt;&lt;SPAN&gt; that function also expects the "lookup value", not the already transformed one!&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;If you give it the LUT value (again) the GPDMA will crash later, if you give it the real address, it will crash when trying to use it for look-up.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I found no way to resolve the problem with the current DAC API.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;My workaround does not look nice, I had to create a temporary LLI to get the second function working:&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;
// fill in the real LLI, this also calculates the correct control word
Chip_GPDMA_PrepareDescriptor(LPC_GPDMA,&amp;amp;daclli, (uint32_t)dacfield, GPDMA_CONN_DAC, 1024, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &amp;amp;daclli);

// create a temporary LLI for the API call, this can be discarded after the call
templli.ctrl=daclli.ctrl;
templli.lli=(uint32_t)&amp;amp;daclli;
templli.src=daclli.src;
templli.dst=GPDMA_CONN_DAC;

// now arm the channel for transfers , the chain starts with the real LLI
Chip_GPDMA_SGTransfer(LPC_GPDMA, dmaChannelNum, &amp;amp;templli, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA);&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;If I have not overlooked the simple &amp;amp; easy solution I'd suggest a change in the API to use "cooked" and "real" values in a more consistent way. &lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;However, once you &lt;/SPAN&gt;&lt;STRONG&gt;get &lt;/STRONG&gt;&lt;SPAN&gt; the GPDMA/DAC running, it's a charm&amp;nbsp; &lt;SPAN class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;&lt;LI-EMOJI id="lia_slightly-smiling-face" title=":slightly_smiling_face:"&gt;&lt;/LI-EMOJI&gt;&lt;/SPAN&gt; . With a single LLI descriptor, linked back to itself, you have a complete function generator running in the background ...&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Best regards,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Mike&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;BR /&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Wed, 15 Jun 2016 20:23:30 GMT</pubDate>
    <dc:creator>lpcware</dc:creator>
    <dc:date>2016-06-15T20:23:30Z</dc:date>
    <item>
      <title>GPDMA + DAC, V2.12</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/GPDMA-DAC-V2-12/m-p/583777#M20922</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;STRONG&gt;Content originally posted in LPCWare by mch0 on Sat Sep 13 15:25:48 MST 2014&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN&gt;Hi,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;when I tried to run the DAC by GPDMA I ran into two problems with the current LPCOpen libraries (2.12). The good news first: Finally all runs as expected. But I think there is room for improvement for an upcoming 2.13 of LPCOpen.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;1. Transfer width&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;The DAC has a 32bit register for the value, all right. However, only the lower halfword contains the value that will be converted, the upper halfword contains static information.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;So when you create a table im memory for DAC output, you would naturally use a table with 16bit entries. &lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;However, in LPCOpen 2.12 the "natural width" for the DAC is looked up as a WORD, i.e. 32 bit.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;These values are predefined in a lookup table in &lt;/SPAN&gt;&lt;I&gt;gpdma_18xx_43cc.c&lt;/I&gt;&lt;SPAN&gt;:&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;/* Optimized Peripheral Source and Destination transfer width (18xx,43xx) */
static const uint8_t GPDMA_LUTPerWid[] = {
...&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I suggest to change the entry for the DAC (third from bottom) from &lt;/SPAN&gt;&lt;I&gt;GPDMA_WIDTH_WORD&lt;/I&gt;&lt;SPAN&gt; to &lt;/SPAN&gt;&lt;I&gt;GPDMA_WIDTH_HALFWORD&lt;/I&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;With that the DMA will write only the lower 16 bits into the DAC value register - works perfectly. This cuts the table space in memory in half. The DMA also uses less bandwith, since the memory read requests are also halved.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;2. GPDMA setup&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;I found it very complicated to set up a linked list transfer, when a peripheral is involved. I am not sure whether I missed the "easy" way, but here it goes.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;When you use linked lists you have to provide the (chain of) LLI descriptors. There is a function to help you prepare one: &lt;/SPAN&gt;&lt;I&gt;Chip_GPDMA_PrepareDescriptor()&lt;/I&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;That's fine, because you don't want to calculate the control word entry yourself.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;But: This function expects a lookup value for a peripheral, if one is used.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;So you don't enter the "real target" but e.g. &lt;/SPAN&gt;&lt;I&gt;GPDMA_CONN_DAC&lt;/I&gt;&lt;SPAN&gt; for the DAC. The function then looks up the target address for you (fine) and uses this value also for other calculations.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;After the call this entry is replaced by the real address (fine again).&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;But after preparing the LLI you have to pass a pointer to it when you prepare the actual transfer with&lt;/SPAN&gt;&lt;BR /&gt;&lt;I&gt;Chip_GPDMA_SGTransfer()&lt;/I&gt;&lt;SPAN&gt; that function also expects the "lookup value", not the already transformed one!&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;If you give it the LUT value (again) the GPDMA will crash later, if you give it the real address, it will crash when trying to use it for look-up.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I found no way to resolve the problem with the current DAC API.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;My workaround does not look nice, I had to create a temporary LLI to get the second function working:&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;
// fill in the real LLI, this also calculates the correct control word
Chip_GPDMA_PrepareDescriptor(LPC_GPDMA,&amp;amp;daclli, (uint32_t)dacfield, GPDMA_CONN_DAC, 1024, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &amp;amp;daclli);

// create a temporary LLI for the API call, this can be discarded after the call
templli.ctrl=daclli.ctrl;
templli.lli=(uint32_t)&amp;amp;daclli;
templli.src=daclli.src;
templli.dst=GPDMA_CONN_DAC;

// now arm the channel for transfers , the chain starts with the real LLI
Chip_GPDMA_SGTransfer(LPC_GPDMA, dmaChannelNum, &amp;amp;templli, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA);&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;If I have not overlooked the simple &amp;amp; easy solution I'd suggest a change in the API to use "cooked" and "real" values in a more consistent way. &lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;However, once you &lt;/SPAN&gt;&lt;STRONG&gt;get &lt;/STRONG&gt;&lt;SPAN&gt; the GPDMA/DAC running, it's a charm&amp;nbsp; &lt;SPAN class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;&lt;LI-EMOJI id="lia_slightly-smiling-face" title=":slightly_smiling_face:"&gt;&lt;/LI-EMOJI&gt;&lt;/SPAN&gt; . With a single LLI descriptor, linked back to itself, you have a complete function generator running in the background ...&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Best regards,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Mike&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;BR /&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 15 Jun 2016 20:23:30 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/GPDMA-DAC-V2-12/m-p/583777#M20922</guid>
      <dc:creator>lpcware</dc:creator>
      <dc:date>2016-06-15T20:23:30Z</dc:date>
    </item>
    <item>
      <title>Re: GPDMA + DAC, V2.12</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/GPDMA-DAC-V2-12/m-p/583778#M20923</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;This is a very, very helpful post. Please LPCXpresso support consider making a FAQ on this or even take care of this in the upcoming realese of the LPCOpen!&lt;BR /&gt;Many thanks to mch0 for all his posts about the LPC4370, they are helping me a lot with my thesis.&lt;BR /&gt;&lt;BR /&gt;Cheers,&lt;BR /&gt;Andrea&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 19 Sep 2016 08:33:58 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/GPDMA-DAC-V2-12/m-p/583778#M20923</guid>
      <dc:creator>a_bet</dc:creator>
      <dc:date>2016-09-19T08:33:58Z</dc:date>
    </item>
    <item>
      <title>Re: GPDMA + DAC, V2.12</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/GPDMA-DAC-V2-12/m-p/583779#M20924</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;This is a very interesting read indeed! I am stuck with a similar problem with linked lists, and I can't seem to get it up and running.&amp;nbsp;What I am trying to accomplish is to output a frame buffer to a display through the SSP. The frame buffer size is too large to be output&amp;nbsp;through one DMA transfer, which is why I am trying to accomplish it through 3 transfers linked together.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As far as I understand from your explanation of the double look up bug and from my own poking around LPCOpen, it should be necessary to create the temporary list for the first descriptor - the one actually fed to Chip_GPDMA_SGTransfer, the following descriptors should work fine, after initialization with Chip_GPDMA_PrepareDescriptor?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;After I have created a temp descriptor my code no longer crashes, however, only the first transfer is completed (1/3) of the display is drawn. It seems that the subsequent lists are&amp;nbsp;never executed, also the&amp;nbsp;DMA Interrupt&amp;nbsp;routine is never called (if I set the lli of descriptor_1 to 0, it is called).&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I would be very grateful, if someone could shed some light on what it is, that I am not understanding/have goofed up! My code is as follows:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;DMA_TransferDescriptor_t descriptor_1;&lt;BR /&gt; DMA_TransferDescriptor_t descriptor_2;&lt;BR /&gt; DMA_TransferDescriptor_t descriptor_3;&lt;BR /&gt; DMA_TransferDescriptor_t temp_descriptor_1;&lt;BR /&gt;&lt;BR /&gt; Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &amp;amp;descriptor_1, (uint32_t)&amp;amp;(display_config-&amp;gt;fb[0]), display_config-&amp;gt;dma_connection, FB_SIZE/3, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &amp;amp;descriptor_1);&lt;BR /&gt; Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &amp;amp;descriptor_2, (uint32_t)&amp;amp;(display_config-&amp;gt;fb[FB_SIZE/3]), display_config-&amp;gt;dma_connection, FB_SIZE/3, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &amp;amp;descriptor_3);&lt;BR /&gt; Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &amp;amp;descriptor_3, (uint32_t)&amp;amp;(display_config-&amp;gt;fb[FB_SIZE/3 * 2]), display_config-&amp;gt;dma_connection, FB_SIZE/3, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, 0);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;temp_descriptor_1.ctrl = descriptor_1.ctrl;&lt;BR /&gt; temp_descriptor_1.lli = (uint32_t)&amp;amp;descriptor_2;&lt;BR /&gt; temp_descriptor_1.src = descriptor_1.src;&lt;BR /&gt; temp_descriptor_1.dst = display_config-&amp;gt;dma_connection;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Chip_GPDMA_SGTransfer(LPC_GPDMA, display_config-&amp;gt;dma_channel, &amp;amp;temp_descriptor_1, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA);&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Best regards,&lt;/P&gt;&lt;P&gt;Denis&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 23 Nov 2017 23:55:32 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/GPDMA-DAC-V2-12/m-p/583779#M20924</guid>
      <dc:creator>denistcherniak</dc:creator>
      <dc:date>2017-11-23T23:55:32Z</dc:date>
    </item>
  </channel>
</rss>

