cancel
Showing results for 
Search instead for 
Did you mean: 

Receiving duplicate bytes in DMA output

Gordon Madden
Associate III
Posted on October 31, 2017 at 21:32

My project involves sending packets of bytes out of the serial port using DMA. I am using an STM32F417 with DMA2 using USART3. DMA transmit buffer is set to The packets that stream the current head position (live) are 66 bytes and stream at 10Hz. Occasionally, longer packets of camera head moves that were previously recorded to flash are sent. This is where I started to notice problems in the DMA output.

00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 23 56 89

00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 23 56 89

00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 23 56 89

00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 23 23 56 89

00 00 00 00 00 00 00 00 00 00 00 00 00 00 19 23 56 89

00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 23 56 89

00 00 00 00 00 00 00 00 00 00 00 00 00 00 1B 23 56 89

00 00 00 00 00 00 00 00 00 00 00 00 00 00 1C 23 56 89

The above packets are frames from a camera move and at frame 18 (which is hex, so that's frame 24), there is an extra byte inserted (in this case, an extra '23'). This happens every time the frame number is 0x

To check out the whole buffer, I filled the buffer with 398 sequential bytes. Here are the results.

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

10 11 12 13 14 15 16 17 18 19 19 1A 1B 1C 1D 1E 1F

20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F

30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F

40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F

50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F

60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F

70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F

80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F

90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F

A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF

B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF

C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF

D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF

E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF

F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

10 11 12 13 14 15 16 17 18 19 19 1A 1B 1C 1D 1E 1F

20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F

30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F

40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F

50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F

60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F

70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F

80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D

The numbers rolled over, which was expected, but the duplicate '19's were not expected.

The duplicate bytes were verified to not be in the transmit buffer before sending. The same is true with the packets above.

I'm not sure how to troubleshoot this because the programmer doesn't have access to internal buffers that the dma uses.

Any suggestions on what the problem may be or how to troubleshoot? Thanks!

#packets #dma #stm32f4 #duplicate

Note: this post was migrated and contained many threaded conversations, some content may be missing.
1 ACCEPTED SOLUTION

Accepted Solutions
Gordon Madden
Associate III
Posted on November 01, 2017 at 19:43

Sorry everybody! It turned out to be the version of Hyperterminal that I was using.

I set up the same test using just USART3 and got the same results (still using Hyperterminal), so that ruled out the DMA part of the problem.

I ran the same tests (working backwards from USART only transfers) and had no problems with any of the packet transfers or tests using RealTerm3.

Much thanks to those who contributed and to Jan, who nudged me in the right direction to look outside the system for some other cause.

Just for reference, I was using version 5.1.2600.0 of HT from 2001. It's a free version that has been kicking around the office here for years, but I guess it's always good to re-evaluate your tools from time to time!

Cheers!

View solution in original post

13 REPLIES 13
Posted on October 31, 2017 at 21:49

Don't know, are you modifying registers?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 31, 2017 at 22:17

DMA registers? Just the enable/disable.

I enable the DMA and have the transfer complete interrupt handler turn it off.

Posted on October 31, 2017 at 22:28

You don't give us enough information but my crystal ball whispered: Camera? DMA2? He might be using DCMI, and then it might've been related to the DMA2 data corruption when managing AHB and APB peripherals in a concurrent way erratum.

Or

https://community.st.com/0D50X00009XkW5oSAF

.

JW

Posted on October 31, 2017 at 22:47

These packets are position data (at 120Hz) for a movie camera head, so no DCIM. It's just position, or for these packets, velocity (change in position) data that was stored during a camera move.

Thanks for contributing. I will check out your suggestion. It's probably something I should know!

Posted on October 31, 2017 at 22:54

Is this problem related to

https://community.st.com/0D50X00009XkYIZSA3

older post? Was that ever resolved? Do you perform M2M transfers on the same DMA2 while the USART DMA is running? Are there any other transfers on that DMA going on at that moment? If yes, doesn't removing some of them solve the problem? How exactly do you set up that DMA transfer, do you use FIFO in DMA? Can't the problem be on the receiving side of UART?

JW

Posted on October 31, 2017 at 23:43

That post was when I was setting up the DMA, and I am using it for all serial communication.The original problem was resolved. I think it involved using a character pointer when addressing 32-bit data, but I can't remember for sure. I will post if I can figure out what it was.

I am not using any M2M, only peripherals, and I have logic that waits for DMA to complete before starting another transfer.

FIFO is off in the final set up.

dma_uart_TX2.DMA_Channel                              = DMA_Channel_4;                            // Channel 0-7

    dma_uart_TX2.DMA_Memory0BaseAddr        = (uint32_t)dma2TxBuffer;                 // Address of SOURCE memory

    dma_uart_TX2.DMA_PeripheralBaseAddr        = (uint32_t)&USART3->DR;              // Address of DESTINATION memory                

    dma_uart_TX2.DMA_MemoryDataSize            = DMA_MemoryDataSize_Byte;        // byte, half, word

    dma_uart_TX2.DMA_PeripheralDataSize        = DMA_PeripheralDataSize_Byte;       // byte, half, word

    dma_uart_TX2.DMA_DIR                                 = DMA_DIR_MemoryToPeripheral;       // M2M (DMA2 only), M2P, P2M

    dma_uart_TX2.DMA_Mode                              = DMA_Mode_Normal;                         // Non-circular

    dma_uart_TX2.DMA_MemoryInc                      = DMA_MemoryInc_Enable;               // Increment memory

    dma_uart_TX2.DMA_PeripheralInc                   = DMA_PeripheralInc_Disable;          // Increment memory

    dma_uart_TX2.DMA_BufferSize                      = DMA1_TX_BUFFER_SIZE;            //

    dma_uart_TX2.DMA_Priority                            = DMA_Priority_High;                        // Very High, High, Medium, Low

    dma_uart_TX2.DMA_MemoryBurst                  = DMA_MemoryBurst_Single;           //

    dma_uart_TX2.DMA_PeripheralBurst              = DMA_PeripheralBurst_Single;       //

    dma_uart_TX2.DMA_FIFOMode                      = DMA_FIFOMode_Disable;   

The receiving side of UART? Maybe, but UART only receives from DMA and sends it out. I don't know how I would check that.

Posted on November 01, 2017 at 08:47

I am not using any M2M, only peripherals,

Namely? If you switch their DMA off, one by one perhaps, is the problem still present?

dma2TxBuffer

What address is that, absolutely? I mean, exactly in the example which provided duplicate 0x19 - weren't they on a 256-byte boundary?

I am trying to find out what may be the source of that astonishing synchronicity, every 256 characters, that's very suspicious.

Don't you by any means overclock the chip, or run it at a voltage lower than needed for given SYSCLK? What happens if you decrease SYSCLK say to a half (the UART will then transmit at half the baudrate which should be no problem for most sane terminals/receivers)?

The receiving side of UART? Maybe, but UART only receives from DMA and sends it out. I don't know how I would check that.

I mean the terminal/receiving software, or UART-to-USB transceiver, everything is under suspicion, so try alternatives on all intermediate points. Do you have a LA or oscilloscope capable of capturing the UART stream?

JW

Alan Chambers
Associate II
Posted on November 01, 2017 at 11:19

What is the relationship between the 400-byte DMA TX buffer and the 66-byte packets? Why not a multiple of 66? How are packets copied into the buffer? It would be easy to create off-by-one errors when concatenating packets. What triggers the start of a DMA transfer? Are you certain you are not overlapping transfers in some way? Can you make a minimal complete program that demonstrates the issue?

Posted on November 01, 2017 at 16:51

Good questions!

There is no relationship between the streaming packets and transferred packets other than I wanted the buffer to be larger than the largest packet I would send. When transferring a move, I pack multiple frames into the buffer to minimize the number of transfers.

How would a multiple of 66 help? The streaming packets are sent at a constant rate, 10Hz.

Packets are copied one byte at a time and transferred to the buffer like this:

   dma2TxBuffer[ dma2WriteHead ] = inChar;

The write head just moves along the buffer.

DMA transfer is triggered by sending the number of bytes to transfer to this function:

   //------------------------------------------------------------------------------------

void SetupDMA2Transmit( u32 transmitBytes )

//------------------------------------------------------------------------------------

{

    USART_ClearFlag(USART3, USART_FLAG_TC);    // clear transmission complete flag

    

    DMA1_Stream3->NDTR = transmitBytes;

    DMA1_Stream3->M0AR = (uint32_t)dma2TxBuffer;

    DMA_ITConfig(DMA1_Stream3,DMA_IT_TC, ENABLE);                        // Interrupt Configuration

    DMA_Cmd(DMA1_Stream3,ENABLE);

}

I check that the transfer DMA has been disabled (meaning that the previous transfer is complete) before starting a new transfer.

I did make a function not related to the packet generating functions. It fills the transfer buffer with sequential bytes and then initiates the transfer. RESULT: the first byte is 0 and then they count up. At 0x19 (27th byte), the next byte is 0x19. it then continues to count up to 256 (max for byte), rolls over to 0 and continues to count up. When 0x19 is encountered again, it duplicates again.

Compare that to sending a prerecorded move. While sending blocks of frames (18 bytes each), mostly filling the buffer, the 25th frame sent (which is in the second buffer-load), a single byte WITHIN that frame gets duplicated. There seems to be no correlation between position of the byte in the transfer buffer and anything else. But again, when that 25th packet transmits, that same byte is duplicated in the same position within the frame.

So, I am getting the same type of behavior in packet and non-packet transfers, and they are consistent within themselves, but not to each other.

Also, the streaming packets (66 bytes) do not have any duplicate bytes. I have been recording the output using hyperterminal and the streaming packets are fine over thousands of iterations.

I hope this gives you some additional insight!