• AVR Freaks

Hot!Why is DMA transferring garbage to first 7 bytes?

Author
m4l490n
Senior Member
  • Total Posts : 121
  • Reward points : 0
  • Joined: 2010/06/15 22:21:39
  • Location: 0
  • Status: offline
2019/07/22 19:31:13 (permalink)
0

Why is DMA transferring garbage to first 7 bytes?

Hello
I'm working with DMA and it's behaving weird. I have configured DMA channel 7 for UART reception like this:
 
static uint8_t Reception_Buffer[96] __attribute__((aligned(16)))

INTSetVectorPriority(INT_VECTOR_DMA(DMA_CHANNEL7), (configKERNEL_INTERRUPT_PRIORITY + 1));
INTSetVectorSubPriority(INT_VECTOR_DMA(DMA_CHANNEL7), configMAX_SYSCALL_INTERRUPT_PRIORITY);

DmaChnOpen(DMA_CHANNEL7,
                        DMA_CHN_PRI2,
                        DMA_OPEN_AUTO | DMA_OPEN_DEFAULT);

INTEnable(INT_SOURCE_DMA(DMA_CHANNEL7), INT_ENABLED);

DmaChnSetMatchPattern(DMA_CHANNEL7, '\n');
DmaChnSetEvEnableFlags(DMA_CHANNEL7, DMA_EV_BLOCK_DONE);

DmaChnSetEventControl(DMA_CHANNEL7,
                                          DMA_EV_START_IRQ(_UART5_RX_IRQ));

DmaChnSetTxfer(DMA_CHANNEL7,
                              U5RXREG,
                              Reception_Buffer,
                              1,
                              sizeof(Reception_Buffer),
                              1);

DmaChnEnable(DMA_CHANNEL7);
[code][/code]
 
I have a breakpoint in my code as soon as the DMA Block Done interrupt is generated. When the code stops in this ISR (vDMA7InterruptHandler), I see that Reception_Buffer that is where the DMA is configured to place the bytes received, has the first 7 bytes as 0xFF, then the valid data is found from the 8th byte. I don't know why this is happening, it's messing up my communications. I don't know whether the DMA is writing the first bytes as 0xFF or if it's starting the transfer at byte 8. I know it's configured correctly because the values in the registers are correct.
 
  • DCH7SSA = 0x1F806A30
  • DCH7DSA = 0x00013D90 <--- This is exactly the start of the Reception_Buffer array.
 
Am I configuring the DMA correctly? What am I missing?
#1

7 Replies Related Threads

    rjc101
    Super Member
    • Total Posts : 101
    • Reward points : 0
    • Joined: 2016/07/08 14:56:34
    • Location: 0
    • Status: offline
    Re: Why is DMA transferring garbage to first 7 bytes? 2019/07/23 08:23:37 (permalink)
    0
    I have a macro for any variable that touches DMA
     
    #define DMA_READY __attribute__((coherent)) __attribute__((aligned(16)))

    The I define the variable with
    static uint8_t DMA_READY Reception_Buffer[96]

    From memory I believe you need the choerent attribute for DMA transfers to put the variable into the uncached memory region.
    post edited by rjc101 - 2019/07/23 08:24:54
    #2
    jg_ee
    Super Member
    • Total Posts : 159
    • Reward points : 0
    • Joined: 2015/04/30 10:54:52
    • Location: Colorado
    • Status: offline
    Re: Why is DMA transferring garbage to first 7 bytes? 2019/07/24 15:34:02 (permalink)
    0
    Maybe something with how your FIFO/INTS are configured for the USART module?
    #3
    m4l490n
    Senior Member
    • Total Posts : 121
    • Reward points : 0
    • Joined: 2010/06/15 22:21:39
    • Location: 0
    • Status: offline
    Re: Why is DMA transferring garbage to first 7 bytes? 2019/07/26 18:08:32 (permalink)
    0
    rjc101
    I have a macro for any variable that touches DMA
     
    #define DMA_READY __attribute__((coherent)) __attribute__((aligned(16)))

     



    Thanks for helping, but this didn't have any effect, I still get the error after defining the variable with the attributes.
    #4
    m4l490n
    Senior Member
    • Total Posts : 121
    • Reward points : 0
    • Joined: 2010/06/15 22:21:39
    • Location: 0
    • Status: offline
    Re: Why is DMA transferring garbage to first 7 bytes? 2019/07/26 18:34:32 (permalink)
    0
    Justin Grantham
    Maybe something with how your FIFO/INTS are configured for the USART module?




    I noticed that I'm not configuring the FIFO INTs and I added the following to my code:
     
    UARTSetFifoMode(UART5, UART_INTERRUPT_ON_RX_NOT_EMPTY);

     
    But that didn't help either. I don't know what else to do! sad: sad
    #5
    nigelwright7557
    Super Member
    • Total Posts : 276
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: Why is DMA transferring garbage to first 7 bytes? 2019/07/27 16:31:07 (permalink)
    0
    rjc101
     
    From memory I believe you need the choerent attribute for DMA transfers to put the variable into the uncached memory region.


    I got caught out with that too with PIC32 usb buffers.
    USB DMA's the data in so the cache isn't updated.
    This messes up data.
    To get around it the buffers need to be set to coherent.
    Worked for me.
     
    #6
    nigelwright7557
    Super Member
    • Total Posts : 276
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: Why is DMA transferring garbage to first 7 bytes? 2019/07/28 21:52:24 (permalink)
    0
    Here is the code I used to fix the problem on my buffer.
    unsigned short __attribute__((coherent)) scopebuffer[2048];
     
    Just yesterday I got caught out with usb scope buffer.
    Most of the data was ok but some of it was wrong causing a distorted sine wave to be displayed.
     
    post edited by nigelwright7557 - 2019/07/28 21:53:25
    #7
    moser
    Super Member
    • Total Posts : 490
    • Reward points : 0
    • Joined: 2015/06/16 02:53:47
    • Location: Germany
    • Status: offline
    Re: Why is DMA transferring garbage to first 7 bytes? 2019/07/29 02:03:16 (permalink)
    0
    There are two things: 
     
    First, the PIC usually uses the cache, while the DMA works with the (uncached) memory directly. So the memory used by DMA and the cache used by the PIC would get out of sync unless you implicitly care about it. Using __attribute__((coherent)) fixes this in an easy way, by moving the data for the PIC into uncached memory.
     
    Second, there was a problem with the compiler. Probably it no longer applies to the latest version, because some stuff got fixed in v1.43. The problem was with the linker or the default linker script. It allowed to place normal cached variables directly next to uncached variables, which where defined with __attribute__((coherent)). And it did even allowed to place them together into the same cache page, which will just cause terrible things, as soon as the cache gets written back to memory. To fix this in an easy way you just make sure that the coherent data always covers the memory of the corresponding cache pages completely. __attribute__((aligned(16))) will do this, as each cache page has 16 bytes. So no cached variable can get placed into the same cache page together with coherent stuff.
     
     
    I don't have any real experience with DMA so I can't help you, m4l490n. The only thing I noticed, is the coincidence that you use the 7th DMA channel and you have 7 byte offset. But I guess you already checked, that nothing got mixed up in that way. 
    #8
    Jump to:
    © 2019 APG vNext Commercial Version 4.5