<?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>Kinetis Microcontrollers中的主题 Re: Why is DMA skipping array values?</title>
    <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918134#M53652</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Paul&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;Generally (although not your issue in this case):&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Note that the SDK reference code uses things like&lt;BR /&gt;DMA_DCR_DSIZE(2)&lt;BR /&gt;which is an incredibly error-prone method.&lt;BR /&gt;You are assuming that DMA_DCR_DSIZE() is set to the correct bits in the register (although probably always correct) and then you need to study the register to find out what 2 means (in the case of this register 1 means "byte", 2 means "half word" and 0 means "long word") but it is up to the programmer to know these details and possibly get it wrong the first time and lose half a day in the process. I have no idea why this technique is used since it would be so simple to make it fool proof with three defines instead.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I didn't originally see the problem so I checked with the uTasker PIT-&amp;gt;DAC DMA reference (after selecting the KL25):&lt;/P&gt;&lt;PRE class=""&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;long&lt;/SPAN&gt; ulDMA_rules &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DIRECTION_OUTPUT &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_HALF_WORDS&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// DMA transfer is from a buffer to a fixed address and each transfer is a half-word in size&lt;/SPAN&gt;
ptrDAC_regs&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DAC_C1 &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;
&lt;SPAN class=""&gt;if&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;dac_mode &lt;SPAN class=""&gt;&amp;amp;&lt;/SPAN&gt; DAC_FULL_BUFFER_DMA_AUTO_REPEAT&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;!=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;{&lt;/SPAN&gt;
    ulDMA_rules &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; DMA_AUTOREPEAT&lt;SPAN class=""&gt;;&lt;/SPAN&gt;
&lt;SPAN class=""&gt;}&lt;/SPAN&gt;
&lt;SPAN class=""&gt;if&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;dac_mode &lt;SPAN class=""&gt;&amp;amp;&lt;/SPAN&gt; DAC_HALF_BUFFER_DMA&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;!=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;{&lt;/SPAN&gt;
    ulDMA_rules &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; DMA_HALF_BUFFER_INTERRUPT&lt;SPAN class=""&gt;;&lt;/SPAN&gt;
&lt;SPAN class=""&gt;}&lt;/SPAN&gt;
&lt;SPAN class=""&gt;fnConfigDMA_buffer&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;ucDmaChannel&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;usDmaTriggerSource&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;ulDAC_buffer_length&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;ptrDAC_Buffer&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_regs&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ulDMA_rules&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;int_handler&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;int_priority&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// source is the DAC buffer and destination is the DAC data[0] register&lt;/SPAN&gt;
&lt;SPAN class=""&gt;if&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;dac_mode &lt;SPAN class=""&gt;&amp;amp;&lt;/SPAN&gt; DAC_BUFFER_DMA_START&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;!=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;{&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;fnDMA_BufferReset&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;ucDmaChannel&lt;SPAN class=""&gt;,&lt;/SPAN&gt; DMA_BUFFER_START&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// start DMA operation&lt;/SPAN&gt;
&lt;SPAN class=""&gt;}&lt;/SPAN&gt;

&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The routine fnConfigDMA_buffer() does the detailed work (and adapts itself to the type of processor and DMA controller in question).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Its operation on the KL25 is (when copying an array of half words to the DAC output - single pass without auto-repeat, with interrupt at end) is - I have also written the hex values that it writes:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class=""&gt;ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DSR_BCR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; DMA_DSR_BCR_DONE&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                              &lt;SPAN class=""&gt;// clear the DONE flag and clear errors etc.&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DCR_DSIZE_16 &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_SSIZE_16 &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_DMOD_OFF &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_SMOD_OFF&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// transfer size half-words [0x00024000]&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DCR_SINC&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                                   &lt;SPAN class=""&gt;// transfers with increment only on source [0x00064000]&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_SAR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;long&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;ptrBufSource&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                       &lt;SPAN class=""&gt;// set source buffer&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DAR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;long&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;ptrBufDest&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                         &lt;SPAN class=""&gt;// set destination buffer&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DSR_BCR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; ulBufLength&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                                   &lt;SPAN class=""&gt;// set transfer count (don't set DMA_DSR_BCR_DONE at the same time otherwise BCR is reset)&lt;/SPAN&gt;
&lt;SPAN class=""&gt;fnEnterInterrupt&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;irq_DMA0_ID &lt;SPAN class=""&gt;+&lt;/SPAN&gt; ucDMA_channel&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;,&lt;/SPAN&gt; int_priority&lt;SPAN class=""&gt;,&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;void&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;*&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;void&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;_DMA_Interrupt&lt;SPAN class=""&gt;[&lt;/SPAN&gt;ucDMA_channel&lt;SPAN class=""&gt;]&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// enter DMA interrupt handler on buffer completion&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DCR_EINT &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_D_REQ&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                   &lt;SPAN class=""&gt;// interrupt when the transmit buffer is empty and stop operation after full buffer has been transferred [0x80640080]&lt;/SPAN&gt;
&lt;SPAN class=""&gt;POWER_UP_ATOMIC&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;6&lt;/SPAN&gt;&lt;SPAN class=""&gt;,&lt;/SPAN&gt; DMAMUX0&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                                         &lt;SPAN class=""&gt;// enable DMA multiplexer 0&lt;/SPAN&gt;
&lt;SPAN class=""&gt;*&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;char&lt;/SPAN&gt; &lt;SPAN class=""&gt;*&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMAMUX0_BLOCK &lt;SPAN class=""&gt;+&lt;/SPAN&gt; ucDMA_channel&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;char&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;usDmaTriggerSource &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMAMUX_CHCFG_ENBL&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// connect trigger to DMA channel&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DCR_CS &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_EADREQ&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                    &lt;SPAN class=""&gt;// enable peripheral request - single cycle for each request (asynchronous requests enabled in stop mode) [0xa0e40080]&lt;/SPAN&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;but then it gave me this exception:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class=""&gt;&lt;SPAN class=""&gt;#if defined ERRATA_ID_5746&lt;/SPAN&gt;
&lt;SPAN class=""&gt;if&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;&amp;amp;&lt;/SPAN&gt; DMA_DCR_CS&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;!=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;{&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;_EXCEPTION&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;"PIT0 trigger generates two data transfers when in cycle-steal mode!!"&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;
&lt;SPAN class=""&gt;}&lt;/SPAN&gt;
&lt;SPAN class=""&gt;#endif&lt;/SPAN&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This is enabled since the KL25 has the mask 2N97F (unless there is a newer one possible) and therefore the errata&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #define ERRATA_ID_5746&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;&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // PIT: when using the PIT to trigger DMA transfers using cycle steal mode, two data transfers per request are generated&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This is the errata description and proposed workarounds:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;e5746: PIT: When using the PIT to trigger DMA transfers using cycle steal mode, two&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;data transfers per request are generated&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;Errata type: Errata&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;Description: If the PIT is used to trigger DMA transfers using cycle steal mode, DMA_DCRn[CS] = 1, each&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;transfer request will cause the source data to be written twice. The data will be written first to&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;the desired destination address and then a second time to the destination address + 1. The&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;destination address pointer increments by 2 for each transfer request.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;Workaround: It is recommended that the PIT not be used for triggering DMA transfers and the low power&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;timer (LPTMR) be used instead.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;If it is required to use the PIT to trigger DMA transfers, the destination address must be in RAM&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;and the buffer size must be twice the amount of data being transferred. Software must then&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;skip every second entry in the destination buffer.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So it turns out that you are probably not doing anything wrong but are being bitten by this chip problem. It looks like you need to use a different DMA trigger source to workaround it in your case. uTasker users are immediately informed of such errata when such use is attempted, which can save quite a large amount of lost time when one doesn't think about checking the erratas.....&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;Regards&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Mark&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;Complete Kinetis solutions for professional needs, training and support: &lt;A href="http://www.utasker.com/kinetis.html" rel="nofollow noopener noreferrer" target="test_blank"&gt;http://www.utasker.com/kinetis.html&lt;/A&gt;&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;Kinetis KL25:&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;- &lt;A href="http://www.utasker.com/kinetis/FRDM-KL25Z.html" rel="nofollow noopener noreferrer" target="test_blank"&gt;http://www.utasker.com/kinetis/FRDM-KL25Z.html&lt;/A&gt;&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;- &lt;A href="http://www.utasker.com/kinetis/TWR-KL25Z48M.html" rel="nofollow noopener noreferrer" target="test_blank"&gt;http://www.utasker.com/kinetis/TWR-KL25Z48M.html&lt;/A&gt;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;SPAN style="color: #000080;"&gt;&lt;EM&gt;uTasker: supporting &amp;gt;1'000 registered Kinetis users get products faster and cheaper to market&lt;/EM&gt;&lt;/SPAN&gt;&lt;BR /&gt;&lt;EM&gt;Request Free emergency remote desk-top consulting at &lt;A href="http://www.utasker.com/services.html" rel="nofollow noopener noreferrer" target="test_blank"&gt;http://www.utasker.com/services.html&lt;/A&gt;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;Open Source version at &lt;A href="https://github.com/uTasker/uTasker-Kinetis" rel="nofollow noopener noreferrer" target="test_blank"&gt;https://github.com/uTasker/uTasker-Kinetis&lt;/A&gt;&lt;/EM&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Tue, 30 Jul 2019 01:40:26 GMT</pubDate>
    <dc:creator>mjbcswitzerland</dc:creator>
    <dc:date>2019-07-30T01:40:26Z</dc:date>
    <item>
      <title>Why is DMA skipping array values?</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918131#M53649</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;On the FRDM-KL25Z, I'm attempting to get DMA to transfer data to DAC, however, it appears to only be transferring only every other value in the source array (second, fourth, sixth etc).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I've gone over the settings and manual countless times and cannot explain this behaviour.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;What I'm looking to achieve is:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;PIT triggers a DMA transfer (CS - one transfer per trigger)&lt;/LI&gt;&lt;LI&gt;DMA transfers one 16-bit integer&amp;nbsp;from the array to the DAC&lt;/LI&gt;&lt;LI&gt;DMA source address increments two bytes&lt;/LI&gt;&lt;LI&gt;Repeat until finished&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;However, what I'm observing is that &lt;STRONG&gt;only every second&lt;/STRONG&gt; integer in the array is transferred, the others are just skipped (no errors etc).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;How I read the manual is that:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;BCR - is the total number of bytes to complete a DMA transfer&lt;/LI&gt;&lt;LI&gt;SSIZE - '2' = 16-bit source values&lt;/LI&gt;&lt;LI&gt;DSIZE - '2' = 16-bit destination values&lt;/LI&gt;&lt;LI&gt;SINC - given the above, increments source by two bytes each time&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;With these settings and an 8 value array of 16-bit integers, only four PIT trigger events occur, on each event the BCR is decremented by 4 bytes and only the even numbered values in the array ever touch the DAC.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I can't reconcile the behaviour I'm seeing with the configuration I've provided.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Please see the source code below, this example just attempts varying levels on the DAC analog out pin (other boiler plate code is assumed), the odd numbered sample values are never transferred (ie. 1000), regardless of value:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#define SAMPLES_SIZE (8)&lt;BR /&gt;uint16_t SAMPLES[SAMPLES_SIZE] = { 1000, 3000, 1000, 3000, 1000, 3000, 1000, 3000 };&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#define LED1 7&lt;BR /&gt;const uint32_t LED_DMA = (1UL &amp;lt;&amp;lt; LED1);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;// These are just debug counter values&lt;/P&gt;&lt;P&gt;volatile uint32_t dma_count = 0;&lt;BR /&gt;volatile uint32_t pit_count = 0;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;void config_dma(void);&lt;BR /&gt;void config_dma(void)&lt;BR /&gt;{&lt;BR /&gt; /* Set source and destination for DMA transfer */&lt;BR /&gt; DMA0-&amp;gt;DMA[0].SAR = DMA_SAR_SAR((uint32_t) SAMPLES);&lt;BR /&gt; DMA0-&amp;gt;DMA[0].DAR = DMA_DAR_DAR((uint32_t) (&amp;amp;(DAC0-&amp;gt;DAT[0])));&lt;BR /&gt; /* Set byte count */&lt;BR /&gt; DMA0-&amp;gt;DMA[0].DSR_BCR = DMA_DSR_BCR_BCR(SAMPLES_SIZE*2);&lt;BR /&gt; /* Clear done flag */&lt;BR /&gt; DMA0-&amp;gt;DMA[0].DSR_BCR &amp;amp;= ~DMA_DSR_BCR_DONE_MASK;&lt;BR /&gt; /* Enable DMA muxer */&lt;BR /&gt; DMAMUX0-&amp;gt;CHCFG[0] |= DMAMUX_CHCFG_ENBL_MASK;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;void PIT_IRQHandler(void)&lt;BR /&gt;{&lt;BR /&gt;pit_count++; // Debug&lt;BR /&gt; PRINTF("p:%u d:%u b:%u\n",pit_count,dma_count, DMA0-&amp;gt;DMA[0].DSR_BCR &amp;amp; DMA_DSR_BCR_BCR_MASK); // Debug&lt;BR /&gt; PIT-&amp;gt;CHANNEL[0].TFLG |= PIT_TFLG_TIF(0);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;void DMA0_IRQHandler(void)&lt;BR /&gt;{&lt;BR /&gt; DMA0-&amp;gt;DMA[0].DSR_BCR |= DMA_DSR_BCR_DONE_MASK;&lt;BR /&gt; config_dma();&lt;BR /&gt; dma_count++; // Debug&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;int main(void) {&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;// Board initialising code omitted&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;// Configure clock for PORTE, DMA Multiplexer, DMA, DAC &amp;amp; PIT&lt;BR /&gt; SIM-&amp;gt;SCGC5 |= SIM_SCGC5_PORTE(1);&lt;BR /&gt; SIM-&amp;gt;SCGC6 |= SIM_SCGC6_DMAMUX(1) | SIM_SCGC6_PIT(1) | SIM_SCGC6_DAC0(1);&lt;BR /&gt; SIM-&amp;gt;SCGC7 |= SIM_SCGC7_DMA(1); &lt;BR /&gt; &lt;BR /&gt; /* Set Port E pin 30 to analog */&lt;BR /&gt; PORTE-&amp;gt;PCR[30] &amp;amp;= ~PORT_PCR_MUX_MASK;&lt;BR /&gt; PORTE-&amp;gt;PCR[30] |= PORT_PCR_MUX(0);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Disable buffer mode */&lt;BR /&gt; DAC0-&amp;gt;C1 = 0;&lt;BR /&gt; DAC0-&amp;gt;C2 = 0;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Enable DAC with VDDA as ref voltage */&lt;BR /&gt; DAC0-&amp;gt;C0 = DAC_C0_DACEN_MASK | DAC_C0_DACRFS_MASK;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;// Disable DMAMUX channel and PIT timer&lt;BR /&gt; DMAMUX0-&amp;gt;CHCFG[0] = 0;&lt;BR /&gt; PIT-&amp;gt;CHANNEL[0].TCTRL &amp;amp;= ~PIT_TCTRL_TEN(1);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;// Configure DMA Source and Destination addresses&lt;BR /&gt; DMA0-&amp;gt;DMA[0].DCR = DMA_DCR_ERQ_MASK | DMA_DCR_CS_MASK | DMA_DCR_EINT_MASK&lt;BR /&gt; | DMA_DCR_SINC_MASK&lt;BR /&gt; | DMA_DCR_SSIZE(2)&lt;BR /&gt; | DMA_DCR_DSIZE(2);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;// Configure PIT - runs off bus clock 24mhz!&lt;BR /&gt; PIT-&amp;gt;CHANNEL[0].LDVAL = (SystemCoreClock/2) - 1; //&amp;nbsp;one second interval&lt;BR /&gt; PIT-&amp;gt;CHANNEL[0].TCTRL |= PIT_TCTRL_TEN(1) | PIT_TCTRL_TIE(1);&lt;BR /&gt; PIT-&amp;gt;MCR = 0; /* Module enabled, don't freeze in debug */&lt;BR /&gt; &lt;BR /&gt; // Enable DMAMUX0 Channel 0, always on and triggered&lt;BR /&gt; DMAMUX0-&amp;gt;CHCFG[0] |= DMAMUX_CHCFG_TRIG(1);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Set up interrupt controller */&lt;BR /&gt; NVIC_SetPriority(PIT_IRQn, 2);&lt;BR /&gt; NVIC_ClearPendingIRQ(PIT_IRQn);&lt;BR /&gt; NVIC_EnableIRQ(PIT_IRQn);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;NVIC_SetPriority(DMA0_IRQn, 0);&lt;BR /&gt; NVIC_ClearPendingIRQ(DMA0_IRQn);&lt;BR /&gt; NVIC_EnableIRQ(DMA0_IRQn);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DMAMUX0-&amp;gt;CHCFG[0] |= DMAMUX_CHCFG_SOURCE(60);&lt;/P&gt;&lt;P&gt;config_dma();&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As always, any help greatly appreciated.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Paul Swanson&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 29 Jul 2019 09:52:12 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918131#M53649</guid>
      <dc:creator>q1220200</dc:creator>
      <dc:date>2019-07-29T09:52:12Z</dc:date>
    </item>
    <item>
      <title>Re: Why is DMA skipping array values?</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918132#M53650</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Paul&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Try doing the copy to a memory array so that you can verify what is actually transferred (this will exclude DAC effects and verify the DMA setup).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Mark&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 29 Jul 2019 16:03:46 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918132#M53650</guid>
      <dc:creator>mjbcswitzerland</dc:creator>
      <dc:date>2019-07-29T16:03:46Z</dc:date>
    </item>
    <item>
      <title>Re: Why is DMA skipping array values?</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918133#M53651</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Good thought. So I implemented a simple array copy and it shows the previously outlined behaviour of only copying every second value from the array.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;#define SAMPLES_SIZE (8)&lt;/P&gt;&lt;P&gt;// Source array&lt;BR /&gt;uint16_t SAMPLES[SAMPLES_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8 };&lt;/P&gt;&lt;P&gt;// Destination array&lt;/P&gt;&lt;P&gt;uint16_t TEST[SAMPLES_SIZE] = { 0xDE, 0xAD, 0xBE, 0xEF,0xDE, 0xAD, 0xBE, 0xEF };&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Then utilising the PIT handler (which I won't eventually need), included the following to observe how the state of the destination array changes with each trigger:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;for (uint32_t i = 0; i &amp;lt; SAMPLES_SIZE; i++) {&lt;BR /&gt; printf("%x ", TEST[i], TEST[i]);&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This results in the following output (one line for each PIT trigger):&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;2 ad be ef de ad be ef &lt;BR /&gt;4 ad be ef de ad be ef &lt;BR /&gt;6 ad be ef de ad be ef &lt;BR /&gt;8 ad be ef de ad be ef&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;However, if I also set the DINC mask, I get the following:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;1 2 be ef de ad be ef &lt;BR /&gt;1 2 3 4 de ad be ef &lt;BR /&gt;1 2 3 4 5 6 be ef &lt;BR /&gt;1 2 3 4 5 6 7 8&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So, with DINC&amp;nbsp;enabled it transfers two bytes at a time. Without DINC, it's just transferring every second byte.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Also, if I reduce the SSIZE and DSIZE to '1' (which should be 1 byte), I see that with DINC enabled it continues to work as expected. However,&amp;nbsp;if I disable DINC, I only get a zero value written to the destination.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So to redefine the problem: DMA transfers only work as expected with DINC enabled.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Paul Swanson&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 29 Jul 2019 22:08:38 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918133#M53651</guid>
      <dc:creator>q1220200</dc:creator>
      <dc:date>2019-07-29T22:08:38Z</dc:date>
    </item>
    <item>
      <title>Re: Why is DMA skipping array values?</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918134#M53652</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Paul&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;Generally (although not your issue in this case):&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Note that the SDK reference code uses things like&lt;BR /&gt;DMA_DCR_DSIZE(2)&lt;BR /&gt;which is an incredibly error-prone method.&lt;BR /&gt;You are assuming that DMA_DCR_DSIZE() is set to the correct bits in the register (although probably always correct) and then you need to study the register to find out what 2 means (in the case of this register 1 means "byte", 2 means "half word" and 0 means "long word") but it is up to the programmer to know these details and possibly get it wrong the first time and lose half a day in the process. I have no idea why this technique is used since it would be so simple to make it fool proof with three defines instead.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I didn't originally see the problem so I checked with the uTasker PIT-&amp;gt;DAC DMA reference (after selecting the KL25):&lt;/P&gt;&lt;PRE class=""&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;long&lt;/SPAN&gt; ulDMA_rules &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DIRECTION_OUTPUT &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_HALF_WORDS&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// DMA transfer is from a buffer to a fixed address and each transfer is a half-word in size&lt;/SPAN&gt;
ptrDAC_regs&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DAC_C1 &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;
&lt;SPAN class=""&gt;if&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;dac_mode &lt;SPAN class=""&gt;&amp;amp;&lt;/SPAN&gt; DAC_FULL_BUFFER_DMA_AUTO_REPEAT&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;!=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;{&lt;/SPAN&gt;
    ulDMA_rules &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; DMA_AUTOREPEAT&lt;SPAN class=""&gt;;&lt;/SPAN&gt;
&lt;SPAN class=""&gt;}&lt;/SPAN&gt;
&lt;SPAN class=""&gt;if&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;dac_mode &lt;SPAN class=""&gt;&amp;amp;&lt;/SPAN&gt; DAC_HALF_BUFFER_DMA&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;!=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;{&lt;/SPAN&gt;
    ulDMA_rules &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; DMA_HALF_BUFFER_INTERRUPT&lt;SPAN class=""&gt;;&lt;/SPAN&gt;
&lt;SPAN class=""&gt;}&lt;/SPAN&gt;
&lt;SPAN class=""&gt;fnConfigDMA_buffer&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;ucDmaChannel&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;usDmaTriggerSource&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;ulDAC_buffer_length&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;ptrDAC_Buffer&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_regs&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ulDMA_rules&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;int_handler&lt;SPAN class=""&gt;,&lt;/SPAN&gt; ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;int_priority&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// source is the DAC buffer and destination is the DAC data[0] register&lt;/SPAN&gt;
&lt;SPAN class=""&gt;if&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;dac_mode &lt;SPAN class=""&gt;&amp;amp;&lt;/SPAN&gt; DAC_BUFFER_DMA_START&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;!=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;{&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;fnDMA_BufferReset&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDAC_settings&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;ucDmaChannel&lt;SPAN class=""&gt;,&lt;/SPAN&gt; DMA_BUFFER_START&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// start DMA operation&lt;/SPAN&gt;
&lt;SPAN class=""&gt;}&lt;/SPAN&gt;

&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The routine fnConfigDMA_buffer() does the detailed work (and adapts itself to the type of processor and DMA controller in question).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Its operation on the KL25 is (when copying an array of half words to the DAC output - single pass without auto-repeat, with interrupt at end) is - I have also written the hex values that it writes:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class=""&gt;ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DSR_BCR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; DMA_DSR_BCR_DONE&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                              &lt;SPAN class=""&gt;// clear the DONE flag and clear errors etc.&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DCR_DSIZE_16 &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_SSIZE_16 &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_DMOD_OFF &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_SMOD_OFF&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// transfer size half-words [0x00024000]&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DCR_SINC&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                                   &lt;SPAN class=""&gt;// transfers with increment only on source [0x00064000]&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_SAR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;long&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;ptrBufSource&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                       &lt;SPAN class=""&gt;// set source buffer&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DAR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;long&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;ptrBufDest&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                         &lt;SPAN class=""&gt;// set destination buffer&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DSR_BCR &lt;SPAN class=""&gt;=&lt;/SPAN&gt; ulBufLength&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                                   &lt;SPAN class=""&gt;// set transfer count (don't set DMA_DSR_BCR_DONE at the same time otherwise BCR is reset)&lt;/SPAN&gt;
&lt;SPAN class=""&gt;fnEnterInterrupt&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;irq_DMA0_ID &lt;SPAN class=""&gt;+&lt;/SPAN&gt; ucDMA_channel&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;,&lt;/SPAN&gt; int_priority&lt;SPAN class=""&gt;,&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;void&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;*&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;void&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;_DMA_Interrupt&lt;SPAN class=""&gt;[&lt;/SPAN&gt;ucDMA_channel&lt;SPAN class=""&gt;]&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// enter DMA interrupt handler on buffer completion&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DCR_EINT &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_D_REQ&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                   &lt;SPAN class=""&gt;// interrupt when the transmit buffer is empty and stop operation after full buffer has been transferred [0x80640080]&lt;/SPAN&gt;
&lt;SPAN class=""&gt;POWER_UP_ATOMIC&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;6&lt;/SPAN&gt;&lt;SPAN class=""&gt;,&lt;/SPAN&gt; DMAMUX0&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                                         &lt;SPAN class=""&gt;// enable DMA multiplexer 0&lt;/SPAN&gt;
&lt;SPAN class=""&gt;*&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;char&lt;/SPAN&gt; &lt;SPAN class=""&gt;*&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMAMUX0_BLOCK &lt;SPAN class=""&gt;+&lt;/SPAN&gt; ucDMA_channel&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;unsigned&lt;/SPAN&gt; &lt;SPAN class=""&gt;char&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;usDmaTriggerSource &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMAMUX_CHCFG_ENBL&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt; &lt;SPAN class=""&gt;// connect trigger to DMA channel&lt;/SPAN&gt;
ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;|&lt;/SPAN&gt;&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;DMA_DCR_CS &lt;SPAN class=""&gt;|&lt;/SPAN&gt; DMA_DCR_EADREQ&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;                    &lt;SPAN class=""&gt;// enable peripheral request - single cycle for each request (asynchronous requests enabled in stop mode) [0xa0e40080]&lt;/SPAN&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;but then it gave me this exception:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class=""&gt;&lt;SPAN class=""&gt;#if defined ERRATA_ID_5746&lt;/SPAN&gt;
&lt;SPAN class=""&gt;if&lt;/SPAN&gt; &lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;ptrDMA&lt;SPAN class=""&gt;-&amp;gt;&lt;/SPAN&gt;DMA_DCR &lt;SPAN class=""&gt;&amp;amp;&lt;/SPAN&gt; DMA_DCR_CS&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;!=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt; &lt;SPAN class=""&gt;{&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;_EXCEPTION&lt;/SPAN&gt;&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;"PIT0 trigger generates two data transfers when in cycle-steal mode!!"&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;SPAN class=""&gt;;&lt;/SPAN&gt;
&lt;SPAN class=""&gt;}&lt;/SPAN&gt;
&lt;SPAN class=""&gt;#endif&lt;/SPAN&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This is enabled since the KL25 has the mask 2N97F (unless there is a newer one possible) and therefore the errata&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #define ERRATA_ID_5746&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;&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // PIT: when using the PIT to trigger DMA transfers using cycle steal mode, two data transfers per request are generated&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This is the errata description and proposed workarounds:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;e5746: PIT: When using the PIT to trigger DMA transfers using cycle steal mode, two&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;data transfers per request are generated&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;Errata type: Errata&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;Description: If the PIT is used to trigger DMA transfers using cycle steal mode, DMA_DCRn[CS] = 1, each&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;transfer request will cause the source data to be written twice. The data will be written first to&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;the desired destination address and then a second time to the destination address + 1. The&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;destination address pointer increments by 2 for each transfer request.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;Workaround: It is recommended that the PIT not be used for triggering DMA transfers and the low power&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;timer (LPTMR) be used instead.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;If it is required to use the PIT to trigger DMA transfers, the destination address must be in RAM&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;and the buffer size must be twice the amount of data being transferred. Software must then&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new, courier, monospace;"&gt;skip every second entry in the destination buffer.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So it turns out that you are probably not doing anything wrong but are being bitten by this chip problem. It looks like you need to use a different DMA trigger source to workaround it in your case. uTasker users are immediately informed of such errata when such use is attempted, which can save quite a large amount of lost time when one doesn't think about checking the erratas.....&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;Regards&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Mark&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;Complete Kinetis solutions for professional needs, training and support: &lt;A href="http://www.utasker.com/kinetis.html" rel="nofollow noopener noreferrer" target="test_blank"&gt;http://www.utasker.com/kinetis.html&lt;/A&gt;&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;Kinetis KL25:&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;- &lt;A href="http://www.utasker.com/kinetis/FRDM-KL25Z.html" rel="nofollow noopener noreferrer" target="test_blank"&gt;http://www.utasker.com/kinetis/FRDM-KL25Z.html&lt;/A&gt;&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;- &lt;A href="http://www.utasker.com/kinetis/TWR-KL25Z48M.html" rel="nofollow noopener noreferrer" target="test_blank"&gt;http://www.utasker.com/kinetis/TWR-KL25Z48M.html&lt;/A&gt;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;SPAN style="color: #000080;"&gt;&lt;EM&gt;uTasker: supporting &amp;gt;1'000 registered Kinetis users get products faster and cheaper to market&lt;/EM&gt;&lt;/SPAN&gt;&lt;BR /&gt;&lt;EM&gt;Request Free emergency remote desk-top consulting at &lt;A href="http://www.utasker.com/services.html" rel="nofollow noopener noreferrer" target="test_blank"&gt;http://www.utasker.com/services.html&lt;/A&gt;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;Open Source version at &lt;A href="https://github.com/uTasker/uTasker-Kinetis" rel="nofollow noopener noreferrer" target="test_blank"&gt;https://github.com/uTasker/uTasker-Kinetis&lt;/A&gt;&lt;/EM&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 30 Jul 2019 01:40:26 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918134#M53652</guid>
      <dc:creator>mjbcswitzerland</dc:creator>
      <dc:date>2019-07-30T01:40:26Z</dc:date>
    </item>
    <item>
      <title>Re: Why is DMA skipping array values?</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918135#M53653</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Wow, I wasn't even daring to suspect a chip issue. Also, fair point about uTasker, I will definitely give it a look soon.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks so much for all your time on this.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Paul Swanson&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 30 Jul 2019 01:51:54 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/Why-is-DMA-skipping-array-values/m-p/918135#M53653</guid>
      <dc:creator>q1220200</dc:creator>
      <dc:date>2019-07-30T01:51:54Z</dc:date>
    </item>
  </channel>
</rss>

