2017-10-31 01:32 PM
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.Solved! Go to Solution.
2017-11-01 11:43 AM
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!
2017-10-31 01:49 PM
Don't know, are you modifying registers?
2017-10-31 03:17 PM
DMA registers? Just the enable/disable.
I enable the DMA and have the transfer complete interrupt handler turn it off.
2017-10-31 03:28 PM
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
2017-10-31 03:47 PM
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!
2017-10-31 03:54 PM
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
2017-10-31 04:43 PM
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.
2017-11-01 01:47 AM
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
2017-11-01 03:19 AM
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?
2017-11-01 09:51 AM
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!