STM 32 DMA SPI - Page 1
Forum section: electronics / general

author: blue0pi
author_rank: Newbie
timestamp: April 23, 2015, 10:45:52 am
content: I have a master, which transfer 20 bytes to slave using SPI transmission every 10ms. It worked fine. The slave received corrected data using DMA SPI.But if the slave received 19 bytes(due to noise or something) and missing one byte. And the master sends the next transfer 20 bytes, the slave received those bytes in wrong order.fx Master sends 10 20 30 40 50, Slave received 50 10 20 30 40I tried to reset DMA but it didn't work(maybe I'm doing its wrong).

author: HackedFridgeMagnet
author_rank: Super Contributor
timestamp: April 23, 2015, 12:29:18 pm
content: Can you reset the peripheral chip?Is it the first byte going missing?Have you got an Oscilloscope? That way you can tell what is actually being sent.

author: poorchava
author_rank: Super Contributor
timestamp: April 23, 2015, 12:47:16 pm
content: I guess you could impose some timeout. If the complete packet doesn't arrive in specified time, then discard received data as incomplete and start over.

author: cyr
author_rank: Frequent Contributor
timestamp: April 23, 2015, 12:51:58 pm
content: Did it really receive the new 20 bytes in the wrong order, or did it receive the "missing" byte followed by 19 new bytes?A byte going missing "due to noise or something" seems less likely to me than getting a byte stuck in a buffer because of some missed detail in the timing of firmware, interrupts, DMA etc. That would explain it popping up in the next transfer...

author: Jeroen3
author_rank: Super Contributor
timestamp: April 23, 2015, 01:12:21 pm
content: It seems the protocol gets out-of-sync.- Sync with a time frame (difficult)- Sync with data pattern (if possible)- Sync with chip select signal.

author: blue0pi
author_rank: Newbie
timestamp: April 23, 2015, 02:20:05 pm
content: I made master send 5 bytes 10 20 30 40 50 every 10 ms. The slave received correctly. I check it with oscilloscope and output the value from slave to my computer via usart.If I use my hand to touch SPI cable and cause noise. The DMA buffer of the slave become out of sync. Bytes received are corrected but not in order 50 10 20 30 40, or 40 50 10 20 30, or 30 40 50 10 20. After that fx everytime master send 10 20 30 40 50 bytes , slave received 50 10 20 30 40I want to reset SPI DMA when things like this happen, so master and slave can be in sync again. I been trying for weeks to reset SPI DMA but no luck :-(It's seems like I can not reset DMA memory pointer either.From data sheetPointer incrementationPeripheral and memory pointers can optionally be automatically post-incremented after each transaction depending on the PINC and MINC bits in the DMA_CCRxregister. If incremented mode is enabled, the address of the next transfer will be the address of the previous one incremented by 1, 2 or 4 depending on the chosen data size. The first transfer address is the one programmed in the DMA_CPARx/DMA_CMARx registers. During transfer operations, these registers keep the initially programmed value. The current transfer addresses (in the current internal peripheral/memory address register) are not accessible by software

author: Jeroen3
author_rank: Super Contributor
timestamp: April 23, 2015, 05:50:08 pm
content: I would assume that writing DMA_CCRx->EN to 0, and then 1, will reset the channel. (and maybe clear channel flags)However, you may need to re-do the initial setup as well. (Which is safe to do anyways)The timing is important, you must do it between the last and first byte of the packet. Otherwise it's you'll be resetting it mid-packet.

author: mikerj
author_rank: Super Contributor
timestamp: April 23, 2015, 06:18:40 pm
content: You have discovered, as I did, that the STM32 SPI peripheral has a (IMO) significant design flaw when used as a slave, i.e. a rising edge on the slave select pin does not terminate the DMA transfer.The easiest I found around this is to configure the slave select pin as an external interrupt, and within the interrupt handler you can check the DMA_CNDTRx register is see if the required amount of data has been received, and if not reset the DMA ready for the next transfer.

author: AndreasF
author_rank: Frequent Contributor
timestamp: April 24, 2015, 06:39:11 am
content: Quote from: mikerj on April 23, 2015, 06:18:40 pmI'm not sure if I would consider this a design flaw. It would require an additional signal to the DMA that may only make sense for certain peripherals (e.g. the mentioned SPI SS going low->high, or I2C stop condition). The DMA doesn't know what type of peripheral it is reading from, it simply gets a DMA transfer request on the channel and then transfers data from one location to another. Similarly the the SPI peripheral doesn't know how the DMA channel is configured.What would be nice is if there was a separate interrupt for the SS pin when used in AF mode by the SPI slave (hardware mode), so that the SPI slave could be automatically activated and deactivated by the SS pin, but that it could signal those changes.Considering that apparently entire bytes are missing (instead of bytes becoming completely mangled), I suspect the SS line is the culprit (assuming it's configured in hardware control mode).Quote