Page 1 of 1

SPI/DMA Filtering frames on the fly

Posted: Tue Jan 19, 2021 6:19 pm
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)

Re: SPI/DMA Filtering frames on the fly

Posted: Wed Jan 20, 2021 9:35 am
by stevestrong
I think you should try

Code: Select all

spi_rx_dma_disable()
, this should avoid any further data reception.

Re: SPI/DMA Filtering frames on the fly

Posted: Wed Jan 20, 2021 5:35 pm
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);
	}

}