SPI/DMA Filtering frames on the fly

Post here first, or if you can't find a relevant section!
Post Reply
Y@@J
Posts: 57
Joined: Mon Sep 28, 2020 8:51 pm

SPI/DMA Filtering frames on the fly

Post by Y@@J »

Hi,

for my app, I need to discard some SPI frames. As I understand SPI+DMA, all frames have to be the same size, the buffer size depending on the frames size. I have some variable length frames that have to be discarded (they are useless). They are easily recognizable with their first byte, and thay are smaller than legit ones.

I solved the problem this way (it works fine) :

- an interrupt on the falling edge of the /CS pin
- an interrupt vector that tests for the buffer's first byte :
- if the first byte is not "legit" -> reset SPI : the whole sequence from setModule() to
spi_rx_dma_enable(), dettaching and reattaching the DMA interrupt. I tried to remove some
functions with no success
- if the first byte is legit, fine, return !

It could take too long (who knows...), so I could miss the next frame from time to time.

Sounds a bit like crap. Doesn't it ? Or as Dave Jones would say : if it looks like..., if it smells like..., it is !
Searching the headers, I didn't find anything that looks like reset or restart. dma_clear_isr_bits() has not the expected effect (it has no effect, but it's only DMA...). It's not enough. Looking for something more brutal, but smarter than what I did.
Is there somethingthat just resets the SPI transfer (and DMA), keeping all the parameters alone ?

(Community Core)
(obviously)
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: SPI/DMA Filtering frames on the fly

Post by stevestrong »

I think you should try

Code: Select all

spi_rx_dma_disable()
, this should avoid any further data reception.
Y@@J
Posts: 57
Joined: Mon Sep 28, 2020 8:51 pm

Re: SPI/DMA Filtering frames on the fly

Post by Y@@J »

Code: Select all

spi_rx_dma_disable()
does not do it (it kills Rx, and

Code: Select all

spi_rx_dma_enable()
is not enough to restore it.

Finally, the simplest (and fastest ?) I could do :

Code: Select all


void ISR_NSS_1() // RISING
{
	volatile uint8_t* p = SPI_1_Rx_Buffer;

	// keep pages only : 0x10 0x00 0xBn (0 <= n < 8)
	if (*p++ != 0x10 || *p++ !=0x00 || *p++ & 0xF0 != 0xB0 || *p & 0x0F > 7)
	{
		dma_disable(SPI_1_DMA, SPI_1_RX_CH);
		dma_tube_cfg(SPI_1_DMA, SPI_1_RX_CH, &SPI_1_DMA_RxTubeCfg);
		dma_enable(SPI_1_DMA, SPI_1_RX_CH);
	}

}
Post Reply

Return to “General discussion”